From d4254bc45858e4d2e9542e5ddf55bd64a98abb25 Mon Sep 17 00:00:00 2001
From: Jean-Francois Remacle <jean-francois.remacle@uclouvain.be>
Date: Wed, 7 Sep 2005 14:36:46 +0000
Subject: [PATCH] Added mesh partitioning (added metis) use it now with
 -partition N for N partitions only works with tets and triangles output
 should be added (useless for now)

---
 Common/CommandLine.cpp   |    13 +-
 Common/Context.h         |     2 +-
 Common/DefaultOptions.h  |     2 +
 Common/Options.cpp       |    13 +-
 Common/Options.h         |     1 +
 Graphics/Geom.cpp        |    14 +-
 Mesh/BDS.cpp             |   196 +-
 Mesh/BDS.h               |    91 +-
 Mesh/Create.cpp          |     6 +-
 Mesh/DiscreteSurface.cpp |   292 +-
 Mesh/Generator.cpp       |     5 +-
 Mesh/Makefile            |     5 +-
 Mesh/Mesh.h              |     4 +-
 Mesh/PartitionMesh.cpp   |   195 +
 Mesh/PartitionMesh.h     |     5 +
 Mesh/Read_Mesh.cpp       |     7 +-
 Metis/Doc/manual.ps      | 16447 +++++++++++++++++++++++++++++++++++++
 Metis/balance.c          |   278 +
 Metis/bucketsort.c       |    43 +
 Metis/ccgraph.c          |   599 ++
 Metis/coarsen.c          |    83 +
 Metis/compress.c         |   256 +
 Metis/debug.c            |   239 +
 Metis/defs.h             |   161 +
 Metis/estmem.c           |   157 +
 Metis/fm.c               |   194 +
 Metis/fortran.c          |   141 +
 Metis/frename.c          |   312 +
 Metis/graph.c            |   616 ++
 Metis/initpart.c         |   422 +
 Metis/kmetis.c           |   129 +
 Metis/kvmetis.c          |   130 +
 Metis/kwayfm.c           |   672 ++
 Metis/kwayrefine.c       |   392 +
 Metis/kwayvolfm.c        |  1778 ++++
 Metis/kwayvolrefine.c    |   460 ++
 Metis/macros.h           |   143 +
 Metis/match.c            |   267 +
 Metis/mbalance.c         |   260 +
 Metis/mbalance2.c        |   328 +
 Metis/mcoarsen.c         |    91 +
 Metis/memory.c           |   208 +
 Metis/mesh.c             |   398 +
 Metis/meshpart.c         |   204 +
 Metis/metis.h            |    37 +
 Metis/mfm.c              |   344 +
 Metis/mfm2.c             |   349 +
 Metis/mincover.c         |   259 +
 Metis/minitpart.c        |   355 +
 Metis/minitpart2.c       |   368 +
 Metis/mkmetis.c          |   123 +
 Metis/mkwayfmh.c         |   677 ++
 Metis/mkwayrefine.c      |   297 +
 Metis/mmatch.c           |   506 ++
 Metis/mmd.c              |   593 ++
 Metis/mpmetis.c          |   402 +
 Metis/mrefine.c          |   219 +
 Metis/mrefine2.c         |    55 +
 Metis/mutil.c            |   101 +
 Metis/myqsort.c          |   547 ++
 Metis/ometis.c           |   764 ++
 Metis/parmetis.c         |   371 +
 Metis/pmetis.c           |   341 +
 Metis/pqueue.c           |   579 ++
 Metis/proto.h            |   505 ++
 Metis/refine.c           |   204 +
 Metis/rename.h           |   418 +
 Metis/separator.c        |   284 +
 Metis/sfm.c              |  1069 +++
 Metis/srefine.c          |   169 +
 Metis/stat.c             |   287 +
 Metis/struct.h           |   251 +
 Metis/subdomains.c       |  1295 +++
 Metis/timing.c           |    74 +
 Metis/util.c             |   519 ++
 Parser/OpenFile.cpp      |     3 +-
 configure                |    54 +
 configure.in             |    32 +-
 78 files changed, 38582 insertions(+), 128 deletions(-)
 create mode 100644 Mesh/PartitionMesh.cpp
 create mode 100644 Mesh/PartitionMesh.h
 create mode 100644 Metis/Doc/manual.ps
 create mode 100644 Metis/balance.c
 create mode 100644 Metis/bucketsort.c
 create mode 100644 Metis/ccgraph.c
 create mode 100644 Metis/coarsen.c
 create mode 100644 Metis/compress.c
 create mode 100644 Metis/debug.c
 create mode 100644 Metis/defs.h
 create mode 100644 Metis/estmem.c
 create mode 100644 Metis/fm.c
 create mode 100644 Metis/fortran.c
 create mode 100644 Metis/frename.c
 create mode 100644 Metis/graph.c
 create mode 100644 Metis/initpart.c
 create mode 100644 Metis/kmetis.c
 create mode 100644 Metis/kvmetis.c
 create mode 100644 Metis/kwayfm.c
 create mode 100644 Metis/kwayrefine.c
 create mode 100644 Metis/kwayvolfm.c
 create mode 100644 Metis/kwayvolrefine.c
 create mode 100644 Metis/macros.h
 create mode 100644 Metis/match.c
 create mode 100644 Metis/mbalance.c
 create mode 100644 Metis/mbalance2.c
 create mode 100644 Metis/mcoarsen.c
 create mode 100644 Metis/memory.c
 create mode 100644 Metis/mesh.c
 create mode 100644 Metis/meshpart.c
 create mode 100644 Metis/metis.h
 create mode 100644 Metis/mfm.c
 create mode 100644 Metis/mfm2.c
 create mode 100644 Metis/mincover.c
 create mode 100644 Metis/minitpart.c
 create mode 100644 Metis/minitpart2.c
 create mode 100644 Metis/mkmetis.c
 create mode 100644 Metis/mkwayfmh.c
 create mode 100644 Metis/mkwayrefine.c
 create mode 100644 Metis/mmatch.c
 create mode 100644 Metis/mmd.c
 create mode 100644 Metis/mpmetis.c
 create mode 100644 Metis/mrefine.c
 create mode 100644 Metis/mrefine2.c
 create mode 100644 Metis/mutil.c
 create mode 100644 Metis/myqsort.c
 create mode 100644 Metis/ometis.c
 create mode 100644 Metis/parmetis.c
 create mode 100644 Metis/pmetis.c
 create mode 100644 Metis/pqueue.c
 create mode 100644 Metis/proto.h
 create mode 100644 Metis/refine.c
 create mode 100644 Metis/rename.h
 create mode 100644 Metis/separator.c
 create mode 100644 Metis/sfm.c
 create mode 100644 Metis/srefine.c
 create mode 100644 Metis/stat.c
 create mode 100644 Metis/struct.h
 create mode 100644 Metis/subdomains.c
 create mode 100644 Metis/timing.c
 create mode 100644 Metis/util.c

diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp
index 3110ead8e6..2d5137ad01 100644
--- a/Common/CommandLine.cpp
+++ b/Common/CommandLine.cpp
@@ -1,4 +1,4 @@
-// $Id: CommandLine.cpp,v 1.63 2005-08-22 00:29:11 geuzaine Exp $
+// $Id: CommandLine.cpp,v 1.64 2005-09-07 14:36:44 remacle Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -73,6 +73,7 @@ void Print_Usage(char *name){
   Msg(DIRECT, "  -algo string          Select mesh algorithm (iso, tri, aniso, netgen, tetgen)");
   Msg(DIRECT, "  -smooth int           Set number of mesh smoothing steps");
   Msg(DIRECT, "  -optimize             Optimize quality of tetrahedral elements");
+  Msg(DIRECT, "  -partition int        Load a mesh and partition it into $1 parts (METIS is required)");
   Msg(DIRECT, "  -order int            Set mesh order (1, 2)");
   Msg(DIRECT, "  -scale float          Set global scaling factor");
   Msg(DIRECT, "  -meshscale float      Set mesh scaling factor");
@@ -353,6 +354,16 @@ void Get_Options(int argc, char *argv[])
           exit(1);
         }
       }
+      else if(!strcmp(argv[i] + 1, "partition")) {
+        i++;
+        if(argv[i] != NULL) {
+          CTX.mesh.nbPartitions = atoi(argv[i++]);
+        }
+        else {
+          fprintf(stderr, ERROR_STR "Missing number\n");
+          exit(1);
+        }
+      }
       else if(!strcmp(argv[i] + 1, "smooth")) {
         i++;
         if(argv[i] != NULL)
diff --git a/Common/Context.h b/Common/Context.h
index cc771fa559..d295c34d4c 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -181,7 +181,7 @@ public :
     double scaling_factor, lc_factor, rand_factor;
     int dual, interactive;
     int light, light_two_side;
-    int format, nb_smoothing, algo2d, algo3d, order,algo_recombine;
+    int format, nbPartitions,nb_smoothing, algo2d, algo3d, order,algo_recombine;
     int point_insertion, speed_max, min_circ_points, constrained_bgmesh;
     int histogram, initial_only;
     double normals, tangents, explode;
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index cd9370cfe3..e1bbd3d088 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -954,6 +954,8 @@ StringXNumber MeshOptions_Number[] = {
     "Global scaling factor applied to the saved mesh" },
   { F|O, "Smoothing" , opt_mesh_nb_smoothing , 1. ,
     "Number of smoothing steps applied to the final mesh" },
+  { F|O, "Partitioning" , opt_mesh_nb_partitions , 1. ,
+    "Number of partitions applied to the final mesh" },
   { F|O, "SmoothNormals" , opt_mesh_smooth_normals , 0. , 
     "Smooth the mesh normals?" },
   { F|O, "SpeedMax" , opt_mesh_speed_max , 0. ,
diff --git a/Common/Options.cpp b/Common/Options.cpp
index c5a8397b08..ec9d5a66ea 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.255 2005-08-24 20:28:42 remacle Exp $
+// $Id: Options.cpp,v 1.256 2005-09-07 14:36:45 remacle Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -4396,6 +4396,17 @@ double opt_mesh_nb_smoothing(OPT_ARGS_NUM)
   return CTX.mesh.nb_smoothing;
 }
 
+double opt_mesh_nb_partitions(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET)
+    CTX.mesh.nbPartitions = (int)val;
+  //#if defined(HAVE_FLTK)
+  //  if(WID && (action & GMSH_GUI))
+  //    WID->mesh_value[0]->value(CTX.mesh.nb_smoothing);
+  //#endif
+  return CTX.mesh.nbPartitions;
+}
+
 double opt_mesh_algo2d(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET){
diff --git a/Common/Options.h b/Common/Options.h
index 4496f08d84..b8db3c4166 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -439,6 +439,7 @@ double opt_mesh_light_two_side(OPT_ARGS_NUM);
 double opt_mesh_format(OPT_ARGS_NUM);
 double opt_mesh_msh_file_version(OPT_ARGS_NUM);
 double opt_mesh_nb_smoothing(OPT_ARGS_NUM);
+double opt_mesh_nb_partitions(OPT_ARGS_NUM);
 double opt_mesh_algo2d(OPT_ARGS_NUM);
 double opt_mesh_recombine_algo(OPT_ARGS_NUM);
 double opt_mesh_algo3d(OPT_ARGS_NUM);
diff --git a/Graphics/Geom.cpp b/Graphics/Geom.cpp
index e116352874..01762f9077 100644
--- a/Graphics/Geom.cpp
+++ b/Graphics/Geom.cpp
@@ -1,4 +1,4 @@
-// $Id: Geom.cpp,v 1.89 2005-07-04 15:07:40 remacle Exp $
+// $Id: Geom.cpp,v 1.90 2005-09-07 14:36:45 remacle Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -150,8 +150,8 @@ void Draw_Curve(void *a, void *b)
       N = 10 * n;
       break;
     }
-    if(c->Typ == MSH_SEGM_DISCRETE && c->bds) {
-      BDS_GeomEntity *g = c->bds->get_geom ( c->Num,1);	
+    if(c->Typ == MSH_SEGM_DISCRETE && THEM->bds) {
+      BDS_GeomEntity *g = THEM->bds->get_geom ( c->Num,1);	
       std::list<BDS_Edge*>::iterator it  = g->e.begin();
       std::list<BDS_Edge*>::iterator ite = g->e.end();
       while (it!=ite){
@@ -349,7 +349,7 @@ void Draw_Polygonal_Surface(Surface * s)
     if(CTX.geom.light) glEnable(GL_LIGHTING);
     glEnable(GL_POLYGON_OFFSET_FILL); // always!
 
-    BDS_GeomEntity *g = s->bds->get_geom ( s->Num,2);	
+    BDS_GeomEntity *g = THEM->bds->get_geom ( s->Num,2);	
 //    if (g->surf) glColor4ubv((GLubyte *) & CTX.color.geom.line);
     std::list<BDS_Triangle*>::iterator it  = g->t.begin();
     std::list<BDS_Triangle*>::iterator ite = g->t.end();
@@ -634,7 +634,7 @@ void Draw_Surface(void *a, void *b)
     glColor4ubv((GLubyte *) & CTX.color.geom.surface);
   }
 
-  if(s->bds){
+  if(THEM->bds){
     Draw_Polygonal_Surface(s);
   }
   else if(s->Typ == MSH_SURF_DISCRETE){
@@ -735,8 +735,8 @@ void HighlightEntity(Vertex * v, Curve * c, Surface * s, int permanent)
 	strcat(Message, "}");
 	Msg(STATUS1N, Message);
       }
-      else if (s->bds){
-	BDS_GeomEntity *g = s->bds->get_geom ( s->Num, 2);
+      else if (THEM->bds){
+	BDS_GeomEntity *g = THEM->bds->get_geom ( s->Num, 2);
 	if (g && g->surf)
 	  Msg(STATUS1N, "Surface %d (%s)", s->Num,g->surf->nameOf().c_str());
 	else
diff --git a/Mesh/BDS.cpp b/Mesh/BDS.cpp
index 25f2a5b366..e5a0f55747 100644
--- a/Mesh/BDS.cpp
+++ b/Mesh/BDS.cpp
@@ -402,6 +402,52 @@ BDS_Edge *BDS_Mesh :: find_edge  (BDS_Point *p1, BDS_Point *p2, BDS_Triangle *t)
     return 0;
 }
 
+
+BDS_Triangle  *BDS_Mesh::find_triangle (BDS_Edge *e1,BDS_Edge *e2,BDS_Edge *e3)
+{
+  int i;
+  for (i=0;i<e1->numfaces();i++) 
+    {
+      BDS_Triangle *t = e1->faces(i); 
+      BDS_Edge *o1 = t->e1;
+      BDS_Edge *o2 = t->e2;
+      BDS_Edge *o3 = t->e3;
+      if ( (o1 == e1 && o2 == e2 && o3 == e3) ||
+	   (o1 == e1 && o2 == e3 && o3 == e2) ||
+	   (o1 == e2 && o2 == e1 && o3 == e3) ||
+	   (o1 == e2 && o2 == e3 && o3 == e1) ||
+	   (o1 == e3 && o2 == e1 && o3 == e2) ||
+	   (o1 == e3 && o2 == e2 && o3 == e1) ) return t;
+    }
+  for (i=0;i<e2->numfaces();i++) 
+    {
+      BDS_Triangle *t = e2->faces(i); 
+      BDS_Edge *o1 = t->e1;
+      BDS_Edge *o2 = t->e2;
+      BDS_Edge *o3 = t->e3;
+      if ( (o1 == e1 && o2 == e2 && o3 == e3) ||
+	   (o1 == e1 && o2 == e3 && o3 == e2) ||
+	   (o1 == e2 && o2 == e1 && o3 == e3) ||
+	   (o1 == e2 && o2 == e3 && o3 == e1) ||
+	   (o1 == e3 && o2 == e1 && o3 == e2) ||
+	   (o1 == e3 && o2 == e2 && o3 == e1) ) return t;
+    }
+  for (i=0;i<e3->numfaces();i++) 
+    {
+      BDS_Triangle *t = e3->faces(i); 
+      BDS_Edge *o1 = t->e1;
+      BDS_Edge *o2 = t->e2;
+      BDS_Edge *o3 = t->e3;
+      if ( (o1 == e1 && o2 == e2 && o3 == e3) ||
+	   (o1 == e1 && o2 == e3 && o3 == e2) ||
+	   (o1 == e2 && o2 == e1 && o3 == e3) ||
+	   (o1 == e2 && o2 == e3 && o3 == e1) ||
+	   (o1 == e3 && o2 == e1 && o3 == e2) ||
+	   (o1 == e3 && o2 == e2 && o3 == e1) ) return t;
+    }
+    return 0;
+}
+
 BDS_Edge *BDS_Mesh :: add_edge  (int p1, int p2)
 {
     BDS_Edge *efound = find_edge (p1,p2);
@@ -420,9 +466,15 @@ BDS_Triangle * BDS_Mesh :: add_triangle  (int p1, int p2, int p3 )
     BDS_Edge *e1=add_edge (p1,p2);
     BDS_Edge *e2=add_edge (p2,p3);
     BDS_Edge *e3=add_edge (p3,p1);
-    //    BDS_Edge *e1 = find_edge (p1,p2); 
-    //    BDS_Edge *e2 = find_edge (p2,p3); 
-    //    BDS_Edge *e3 = find_edge (p3,p1); 
+    return add_triangle(e1,e2,e3);
+}
+
+BDS_Triangle * BDS_Mesh :: add_triangle  (BDS_Edge *e1,BDS_Edge *e2,BDS_Edge *e3)
+{
+
+    BDS_Triangle *tfound = find_triangle (e1,e2,e3);
+    if (tfound)return tfound;
+
     try {
 	BDS_Triangle *t  = new BDS_Triangle ( e1, e2, e3 );    
 	triangles.push_back ( t );
@@ -433,6 +485,23 @@ BDS_Triangle * BDS_Mesh :: add_triangle  (int p1, int p2, int p3 )
       return 0;
     }
 }
+
+BDS_Tet * BDS_Mesh :: add_tet  (int p1, int p2, int p3, int p4 )
+{
+    BDS_Edge *e1=add_edge (p1,p2);
+    BDS_Edge *e2=add_edge (p2,p3);
+    BDS_Edge *e3=add_edge (p3,p1);
+    BDS_Edge *e4=add_edge (p1,p4);
+    BDS_Edge *e5=add_edge (p2,p4);
+    BDS_Edge *e6=add_edge (p3,p4);
+    BDS_Triangle *t1  = add_triangle (e1,e2,e3);
+    BDS_Triangle *t2  = add_triangle (e1,e4,e5);
+    BDS_Triangle *t3  = add_triangle (e2,e6,e5);
+    BDS_Triangle *t4  = add_triangle (e3,e4,e6);
+    BDS_Tet *t  = new BDS_Tet ( t1, t2, t3, t4 );    
+    tets.push_back ( t );    
+    return t;
+}
 void  BDS_Mesh :: del_triangle  (BDS_Triangle *t)
 {
     t->e1->del ( t );
@@ -682,7 +751,7 @@ void BDS_Mesh :: createSearchStructures ( )
 
   printf("creating the ANN search structure\n");
   
-  const double LC_SEARCH = LC *1.e-3;
+  const double LC_SEARCH = LC *.3e-3;
 
   for (std::set<BDS_GeomEntity*,GeomLessThan>::iterator it = geom.begin();
        it != geom.end();
@@ -816,29 +885,43 @@ void BDS_Point :: compute_curvature ( )
 
 int compute_curvatures (std::list<BDS_Edge*> &edges)
 {
-  std::list<BDS_Edge*>::iterator it = edges.begin();
-  std::list<BDS_Edge*>::iterator ite  = edges.end();
-  while (it != ite)
-    {
-      if ((*it)->numfaces() == 2)
-	{
-	  if ((*it)->faces(0)->g == (*it)->faces(1)->g)
-	    {
-	      BDS_Vector N1=(*it)->faces(0)->N();
-	      BDS_Vector N2=(*it)->faces(1)->N();
-	      BDS_Vector C1=(*it)->faces(0)->cog();
-	      BDS_Vector C2=(*it)->faces(1)->cog();
-	      BDS_Vector DIFFN = N2-N1;
-	      BDS_Vector DIST  = C2-C1;
-	      double crv = 1./sqrt((DIFFN*DIFFN)/(DIST*DIST));
-	      if ((*it)->p1->radius_of_curvature > crv)
-		(*it)->p1->radius_of_curvature = crv;
-	      if ((*it)->p2->radius_of_curvature > crv)
-		(*it)->p2->radius_of_curvature = crv;
-	    }
-	}
-      ++it;
-    }
+  {
+    std::list<BDS_Edge*>::iterator it = edges.begin();
+    std::list<BDS_Edge*>::iterator ite  = edges.end();
+    while (it != ite)
+      {
+	(*it)->target_length = 1.e22;
+	(*it)->p1->radius_of_curvature = 1.e22;
+	(*it)->p2->radius_of_curvature = 1.e22;
+	++it;
+      }
+    
+  }
+  {
+    std::list<BDS_Edge*>::iterator it = edges.begin();
+    std::list<BDS_Edge*>::iterator ite  = edges.end();
+    while (it != ite)
+      {
+	if ((*it)->numfaces() == 2)
+	  {
+	    if ((*it)->faces(0)->g == (*it)->faces(1)->g)
+	      {
+		BDS_Vector N1=(*it)->faces(0)->N();
+		BDS_Vector N2=(*it)->faces(1)->N();
+		BDS_Vector C1=(*it)->faces(0)->cog();
+		BDS_Vector C2=(*it)->faces(1)->cog();
+		BDS_Vector DIFFN = N2-N1;
+		BDS_Vector DIST  = C2-C1;
+		double crv = 1./sqrt((DIFFN*DIFFN)/(DIST*DIST));
+		if ((*it)->p1->radius_of_curvature > crv)
+		  (*it)->p1->radius_of_curvature = crv;
+		if ((*it)->p2->radius_of_curvature > crv)
+		  (*it)->p2->radius_of_curvature = crv;
+	      }
+	  }
+	++it;
+      }
+  }
 } 
 
 
@@ -1685,11 +1768,12 @@ void BDS_Mesh :: cleanup()
 
 BDS_Mesh ::~ BDS_Mesh ()
 {
-    DESTROOOY ( geom.begin(),geom.end());
-    DESTROOOY ( points.begin(),points.end());
-    cleanup();
-    DESTROOOY ( edges.begin(),edges.end());
-    DESTROOOY ( triangles.begin(),triangles.end());
+  // DESTROOOY ( geom.begin(),geom.end());
+  //DESTROOOY ( points.begin(),points.end());
+    //cleanup();
+    //    DESTROOOY ( edges.begin(),edges.end());
+    //    DESTROOOY ( triangles.begin(),triangles.end());
+    //    DESTROOOY ( tets.begin(),tets.end());
 }
 
 bool BDS_Mesh ::split_edge ( BDS_Edge *e, double coord, BDS_Mesh *geom )
@@ -1936,8 +2020,13 @@ bool BDS_Mesh ::collapse_edge ( BDS_Edge *e, BDS_Point *p, const double eps)
 
     if (e->numfaces() != 2)return false;
     if (p->g && p->g->classif_degree == 0)return false;
-    if (e->g && e->g->classif_degree == 1)return false;
-
+    // not really ok but 'til now this is the best choice not to do collapses on model edges
+    if (p->g && p->g->classif_degree == 1)return false;
+    if (e->g && p->g)
+      {
+	if(e->g->classif_degree == 2 && p->g != e->g)return false;
+      }
+    
     std::list<BDS_Triangle *> t;
     BDS_Point *o = e->othervertex (p);
 
@@ -2080,7 +2169,7 @@ bool project_point_on_a_list_of_triangles ( BDS_Point *p ,
 	{	  
 	  {
 	    double xp,yp,zp;
-	    bool ok = proj_point_triangle ( p->X,p->Y,p->Z,p->N(),*it,xp,yp,zp);
+	    bool ok = proj_point_triangle ( p->X,p->Y,p->Z,(*it)->N(),*it,xp,yp,zp);
 	    if (ok)
 	      {
 		global_ok = true;
@@ -2092,6 +2181,19 @@ bool project_point_on_a_list_of_triangles ( BDS_Point *p ,
 		    dist2 = d2;
 		  }
 	      }
+// 	    ok = proj_point_triangle ( p->X,p->Y,p->Z,p->N(),*it,xp,yp,zp);
+// 	    if (ok)
+// 	      {
+// 		global_ok = true;
+// 		double d2 = ((xp-X)*(xp-X)+(yp-Y)*(yp-Y)+(zp-Z)*(zp-Z));
+// 		if (d2 < dist2 )
+// 		  {
+// 		    //		    printf("one found among %d\n",t.size());
+// 		    XX = xp; YY = yp; ZZ = zp;
+// 		    dist2 = d2;
+// 		  }
+// 	      }
+
 	  }
 	}
       ++it;
@@ -2209,9 +2311,9 @@ void BDS_Mesh :: compute_metric_edge_lengths (const BDS_Metric & metric)
 						    0.5*(e->p1->Y+e->p2->Y),
 						    0.5*(e->p1->Z+e->p2->Z));
 	    double radius = 1./curvature;
-	    double target = 3.14159 *radius  / metric.nb_elements_per_radius_of_curvature;
+	    double target = radius  / metric.nb_elements_per_radius_of_curvature;
 	    e->target_length = metric.update_target_length (target,e->target_length);
-	    //		printf("e1 radius %g target %g length %g mlp %g ml %g\n",radius, target,e->length(),e->length()/target,e->metric_length);
+	    //	    printf("e1 radius %g target %g length %g mlp %g\n",radius, target,e->length(),e->length()/target);
 	  }
 	else
 	  {
@@ -2264,8 +2366,8 @@ int BDS_Mesh :: adapt_mesh ( double l, bool smooth, BDS_Mesh *geom_mesh)
     SNAP_SUCCESS = 0;
     SNAP_FAILURE = 0;
 
-    BDS_Metric metric ( l , LC/500 , LC, 3 );
-    //    printf("METRIC %g %g %g\n",LC,metric._min,metric._max);
+    BDS_Metric metric ( l , LC/500 , LC, 7 );
+    //    �pr�intf("METRIC %g %g %g\n",LC,metric._min,metric._max);
 
     // add initial set of edges in a list
     std::list<BDS_Edge*> small_to_long;
@@ -2384,7 +2486,7 @@ int BDS_Mesh :: adapt_mesh ( double l, bool smooth, BDS_Mesh *geom_mesh)
 		    double qa = (qa1<qa2)?qa1:qa2; 
 		    double qb = (qb1<qb2)?qb1:qb2; 
 //		  printf("qa %g qb %g ..\n",qa,qb);
-		    if (qb > qa && d < 0.05 * dd )
+		    if (qb > qa && d < 0.01 * dd )
 		    {
 //		      printf("swop ..\n");
 			nb_modif++;
@@ -2459,5 +2561,19 @@ BDS_Mesh::BDS_Mesh (const BDS_Mesh &other)
 	BDS_Triangle *t = add_triangle(n[0]->iD,n[1]->iD,n[2]->iD);
 	t->g = get_geom  ((*it)->g->classif_tag,(*it)->g->classif_degree);
 	t->g->t.push_back(t);
+	t->status = (*it)->status;
+    } 
+
+    for (std::list<BDS_Tet*>::const_iterator it  = other.tets.begin();
+	 it != other.tets.end();
+	 ++it)
+    {
+	BDS_Point *n[4];
+        (*it)->getNodes (n);
+	BDS_Tet *t = add_tet(n[0]->iD,n[1]->iD,n[2]->iD,n[3]->iD);
+	t->g = get_geom  ((*it)->g->classif_tag,(*it)->g->classif_degree);
+	//	t->g->t.push_back(t);
+	t->status = (*it)->status;
     }
+
 }
diff --git a/Mesh/BDS.h b/Mesh/BDS.h
index f217f688f0..7c8a59c281 100644
--- a/Mesh/BDS.h
+++ b/Mesh/BDS.h
@@ -14,6 +14,7 @@
 #include <math.h>
 //#include <algorithm>
 
+class BDS_Tet;
 class BDS_Edge;
 class BDS_Triangle;
 class BDS_Mesh;
@@ -330,6 +331,7 @@ class BDS_Triangle
 public:
     bool deleted;
     int status;
+    BDS_Tet  *t1,*t2;
     BDS_Edge *e1,*e2,*e3;
     BDS_Vector NORMAL;
     double surface;
@@ -337,6 +339,18 @@ public:
     inline double S() const {return surface;}
     BDS_GeomEntity *g;
 
+    inline BDS_Tet * opposite_tet (BDS_Tet *t)
+      {
+	if (t == t1)return t2;
+	if (t == t2)return t1;
+	throw;
+      }
+
+    inline int numtets ( ) const 
+	{
+	  return ( (t1!=0) + (t2 !=0) );
+	}
+
     inline BDS_Vector cog() const
 	{
 	    BDS_Point *n[3];
@@ -364,8 +378,31 @@ public:
 	  n[1] = e1->commonvertex (e2);
 	  n[2] = e2->commonvertex (e3);
 	}
+
+    inline void addtet ( BDS_Tet *t)
+	{
+	  if (!t1) t1 = t;
+	  else if (!t2) t2 = t;
+	  else throw;
+	}
+
+    inline void del (BDS_Tet *t)
+	{
+	  if (t == t1) 
+	    {
+	      t1 = t2;
+	      t2 = 0;
+	    }
+	  else if (t == t2)
+	    {
+	      t2 = 0;
+	    }
+	  else
+	    throw;
+	}
+
     BDS_Triangle ( BDS_Edge *A, BDS_Edge *B, BDS_Edge *C)
-	: deleted (false) , status(0), e1(A),e2(B),e3(C),g(0)
+	: deleted (false) , status(0), t1(0),t2(0),e1(A),e2(B),e3(C),g(0)
 	{	
 	    e1->addface(this);
 	    e2->addface(this);
@@ -374,6 +411,50 @@ public:
 	}
 };
 
+class BDS_Tet
+{
+public:
+    bool deleted;
+    int status;
+    BDS_Triangle  *f1,*f2,*f3,*f4;
+    double volume;
+    inline double V() const {return volume;}
+    BDS_GeomEntity *g;
+
+    inline BDS_Vector cog() const
+	{
+	  BDS_Point *n[4];
+	  getNodes (n);
+	  return BDS_Vector ((n[0]->X+n[1]->X+n[2]->X+n[3]->X)/4.,
+			     (n[0]->Y+n[1]->Y+n[2]->Y+n[3]->Y)/4.,
+			     (n[0]->Z+n[1]->Z+n[2]->Z+n[3]->Z)/4.);
+	}
+
+    inline void _update ()
+      { 
+      }
+
+    inline void getNodes (BDS_Point *n[4]) const
+	{
+	  BDS_Point *o[3];
+	  f1->getNodes (n);
+	  f2->getNodes (o);	  
+	  if(o[0] != n[0] && o[0] != n[1] &&o[0] != n[2])n[3] = o[0];
+	  if(o[1] != n[0] && o[1] != n[1] &&o[1] != n[2])n[3] = o[1];
+	  if(o[2] != n[0] && o[2] != n[1] &&o[2] != n[2])n[3] = o[2];
+	}
+
+    BDS_Tet ( BDS_Triangle *A, BDS_Triangle *B, BDS_Triangle *C, BDS_Triangle *D)
+	: deleted (false) , status(0), f1(A),f2(B),f3(C),f4(D),g(0)
+	{	
+	    f1->addtet(this);
+	    f2->addtet(this);
+	    f3->addtet(this);
+	    f4->addtet(this);
+	    _update();
+	}
+};
+
 
 class BDS_Plane : public  BDS_Surface
 {
@@ -399,7 +480,7 @@ public :
 	} 
     virtual double normalCurv ( double x, double y, double z ) const
 	{
-	    return 0.0;
+	    return 1.e-22;
 	}
 };
 
@@ -495,15 +576,19 @@ class BDS_Mesh
     std::set<BDS_Point*,PointLessThan>     points; 
     std::list<BDS_Edge*>      edges; 
     std::list<BDS_Triangle*>   triangles; 
+    std::list<BDS_Tet*>        tets; 
     BDS_Point * add_point (int num , double x, double y,double z);
     BDS_Edge  * add_edge  (int p1, int p2);
     void del_point  (BDS_Point *p);
     void del_edge  (BDS_Edge *e);
-    BDS_Triangle *add_triangle  (int p1, int p2, int p3);
+    BDS_Triangle *add_triangle  (int p1, int p2, int p3); 
+    BDS_Triangle *add_triangle  (BDS_Edge *e1,BDS_Edge *e2,BDS_Edge *e3);
+    BDS_Tet *add_tet  (int p1, int p2, int p3,int p4);
     void del_triangle  (BDS_Triangle *t);
     void add_geom  (int degree, int tag);
     BDS_Point *find_point (int num);
     BDS_Edge  *find_edge (int p1, int p2);
+    BDS_Triangle  *find_triangle (BDS_Edge *e1,BDS_Edge *e2,BDS_Edge *e3);
     BDS_Edge  *find_edge (BDS_Point *p1, BDS_Point *p2, BDS_Triangle *t)const;
     BDS_GeomEntity *get_geom  (int p1, int p2);
     bool swap_edge ( BDS_Edge *);
diff --git a/Mesh/Create.cpp b/Mesh/Create.cpp
index 3ad7e23549..81f5220cf9 100644
--- a/Mesh/Create.cpp
+++ b/Mesh/Create.cpp
@@ -1,4 +1,4 @@
-// $Id: Create.cpp,v 1.77 2005-07-14 14:28:15 remacle Exp $
+// $Id: Create.cpp,v 1.78 2005-09-07 14:36:45 remacle Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -524,7 +524,7 @@ Curve *Create_Curve(int Num, int Typ, int Order, List_T * Liste,
 			  {1, 0, 0, 0.0} };
 
   Curve *pC = (Curve *) Malloc(sizeof(Curve));
-  pC->bds = 0;
+  //  pC->bds = 0;
   pC->LinVertexArray = NULL;
   pC->Color.type = 0;
   pC->Visible = VIS_GEOM | VIS_MESH;
@@ -650,7 +650,7 @@ void Free_Curve(void *a, void *b)
 Surface *Create_Surface(int Num, int Typ)
 {
   Surface *pS = (Surface *) Malloc(sizeof(Surface));
-  pS->bds = 0;
+  //  pS->bds = 0;
   pS->Color.type = 0;
   pS->Visible = VIS_GEOM | VIS_MESH;
   pS->Num = Num;
diff --git a/Mesh/DiscreteSurface.cpp b/Mesh/DiscreteSurface.cpp
index 87b877b378..47d05cc727 100644
--- a/Mesh/DiscreteSurface.cpp
+++ b/Mesh/DiscreteSurface.cpp
@@ -1,4 +1,4 @@
-// $Id: DiscreteSurface.cpp,v 1.23 2005-08-25 14:56:54 remacle Exp $
+// $Id: DiscreteSurface.cpp,v 1.24 2005-09-07 14:36:45 remacle Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -31,73 +31,197 @@
 
 extern Mesh *THEM;
 extern Context_T CTX;
-
-void Mesh_To_BDS(Surface *s, BDS_Mesh *m)
+extern void Move_SimplexBaseToSimplex(Mesh * M, int dimension);
+void Mesh_To_BDS(Mesh *m)
 {
-  List_T *vertices = Tree2List ( s->Vertices ) ;
+
+  Msg(STATUS2, "Moving the mesh in the new gmsh structure\n");
+  Move_SimplexBaseToSimplex(m, 3);
+  // create the structure
+  if (m->bds)delete m->bds;
+  m->bds = new BDS_Mesh;
+  PhysicalGroup *p;
+
+  m->bds->Min[0] = m->bds->Min[1] = m->bds->Min[2] = 1.e12;
+  m->bds->Max[0] = m->bds->Max[1] =m->bds-> Max[2] = -1.e12;
+
+  Msg(STATUS2, "Moving the nodes\n");
+  // copy the nodes
+  List_T *vertices = Tree2List ( m->Vertices ) ;
   for (int i=0;i<List_Nbr ( vertices ) ;++i)
     {
       Vertex *v;
       List_Read ( vertices, i, &v);
-      m->add_point (v->Num,v->Pos.X,v->Pos.Y,v->Pos.Z); 
+      if ( v->Pos.X < m->bds->Min [0]) m->bds->Min[0] = v->Pos.X;
+      if ( v->Pos.Y < m->bds->Min [1]) m->bds->Min[1] = v->Pos.Y;
+      if ( v->Pos.Z < m->bds->Min [2]) m->bds->Min[2] = v->Pos.Z;
+      if ( v->Pos.X > m->bds->Max [0]) m->bds->Max[0] = v->Pos.X;
+      if ( v->Pos.Y > m->bds->Max [1]) m->bds->Max[1] = v->Pos.Y;
+      if ( v->Pos.Z > m->bds->Max [2]) m->bds->Max[2] = v->Pos.Z;
+      m->bds->add_point (v->Num,v->Pos.X,v->Pos.Y,v->Pos.Z); 
     }
+  m->bds->LC = sqrt ((m->bds->Min[0]-m->bds->Max[0])*(m->bds->Min[0]-m->bds->Max[0])+
+	     (m->bds->Min[1]-m->bds->Max[1])*(m->bds->Min[1]-m->bds->Max[1])+
+	     (m->bds->Min[2]-m->bds->Max[2])*(m->bds->Min[2]-m->bds->Max[2]));
   List_Delete (vertices);
-  List_T *triangles = Tree2List ( s->Simplexes) ;
-  for (int i=0;i<List_Nbr ( triangles ) ;++i)
+
+  for(int i = 0; i < List_Nbr(m->PhysicalGroups); i++) {
+    List_Read(m->PhysicalGroups, i, &p);
+    if(p->Typ == MSH_PHYSICAL_POINT) {
+      m->bds->add_geom  (p->Num,0); 
+      BDS_GeomEntity *g = m->bds->get_geom  (p->Num,0);
+      for(int j = 0; j < List_Nbr(p->Entities); j++) {
+	int Num;
+        List_Read(p->Entities, j, &Num); 
+	BDS_Point *ppp = m->bds->find_point (Num);
+	ppp->g = g;
+	g->p = ppp;
+      }
+    }
+  }
+
+  Msg(STATUS2, "Moving the curves\n");
+  List_T *curves = Tree2List ( m->Curves ) ;
+  for (int i=0;i<List_Nbr ( curves ) ;++i)
     {
+      Curve *c;
+      List_Read ( curves, i, &c);
+      m->bds->add_geom  ( c->Num, 1);
+      BDS_GeomEntity *g = m->bds->get_geom  (c->Num,1);
+      List_T *simplices = Tree2List ( c->Simplexes ) ;
       Simplex *simp;
-      List_Read ( triangles, i, &simp);
-      Vertex *v1 = simp->V[0];
-      Vertex *v2 = simp->V[1];
-      Vertex *v3 = simp->V[2];
-      m->add_triangle (v1->Num,v2->Num,v3->Num); 
+      for (int j=0;j<List_Nbr ( simplices) ;++j)
+	{
+	  List_Read(simplices,j,&simp);
+	  BDS_Edge *edge = m->bds->add_edge (simp->V[0]->Num,simp->V[1]->Num); 
+	  edge->g = g;
+	  if (!edge->p1->g)edge->p1->g = g;
+	  if (!edge->p2->g)edge->p2->g = g;
+	}
+      List_Delete(simplices);
     }
-  List_Delete (triangles);
-
-}
+  List_Delete (curves);
+  Msg(STATUS2, "Moving the surfaces\n");
+  List_T *surfaces = Tree2List ( m->Surfaces ) ;
+  for (int i=0;i<List_Nbr ( surfaces ) ;++i)
+    {
+      Surface *s;
+      List_Read ( surfaces, i, &s);
+      m->bds->add_geom  ( s->Num, 2);
+      BDS_GeomEntity *g = m->bds->get_geom  (s->Num,2);
 
-void BDS_To_Mesh_2(Mesh *m)
-{
-    Msg(STATUS2, "Moving the surface mesh in the old gmsh structure\n");
-    
-    Tree_Action(m->Vertices, Free_Vertex);  
-    Tree_Delete(m->Vertices);
-    m->Vertices = Tree_Create(sizeof(Vertex *), compareVertex);
+      printf("a new surface %d %d is created\n",g->classif_tag,g->classif_degree);
 
-    {
-	std::set<BDS_Point*, PointLessThan>::iterator it   = m->bds_mesh->points.begin();
-	std::set<BDS_Point*, PointLessThan>::iterator ite  = m->bds_mesh->points.end();
-	while (it != ite)
+      List_T *simplices = Tree2List ( s->Simplexes ) ;
+      Simplex *simp;
+      for (int j=0;j<List_Nbr ( simplices) ;++j)
 	{
-	    Vertex *vert = Create_Vertex((*it)->iD, (*it)->X,(*it)->Y,(*it)->Z, 1.0, 0.0);
-	    Tree_Add (m->Vertices,&vert);
-	    ++it;
+	  List_Read(simplices,j,&simp);
+	  BDS_Triangle *t = m->bds->add_triangle (simp->V[0]->Num,simp->V[1]->Num,simp->V[2]->Num); 
+	  t->g = g;	
+	  BDS_Point *n[3];
+	  t->getNodes (n);
+	  for (int K=0;K<3;K++)
+	    if (!n[K]->g) n[K]->g = g;
+	  if (!t->e1->g)t->e1->g = g;
+	  if (!t->e2->g)t->e2->g = g;
+	  if (!t->e3->g)t->e3->g = g;
 	}
+      List_Delete(simplices);
     }
-
+  List_Delete (surfaces);
+  
+  Msg(STATUS2, "Moving the %d volumes\n",Tree_Nbr(m->Volumes));
+  List_T *volumes = Tree2List ( m->Volumes ) ;
+  for (int i=0;i<List_Nbr ( volumes ) ;++i)
     {
-	std::list<BDS_Edge*>::iterator it  = m->bds_mesh->edges.begin();
-	std::list<BDS_Edge*>::iterator ite = m->bds_mesh->edges.end();
-	while(it!=ite)
+      Volume *v;
+      List_Read ( volumes, i, &v);
+      m->bds->add_geom  ( v->Num, 3);
+      BDS_GeomEntity *g = m->bds->get_geom  (v->Num,3);
+      List_T *simplices = Tree2List ( v->Simplexes ) ;
+      Simplex *simp;
+      printf("%d tets\n",List_Nbr ( simplices));
+      for (int j=0;j<List_Nbr ( simplices) ;++j)
 	{
-	    BDS_GeomEntity *g = (*it)->g;
-	    if (g && g->classif_degree == 1)
-	    {
-		Vertex *v1 = FindVertex((*it)->p1->iD, m);
-		Vertex *v2 = FindVertex((*it)->p2->iD, m);
-		SimplexBase *simp = Create_SimplexBase(v1,v2,NULL, NULL);
-		Curve *c = FindCurve (g->classif_tag,m);
-		if (c)
-		    simp->iEnt = g->classif_tag;
-		Tree_Insert(c->SimplexesBase, &simp);
-	    }
-	    ++it;
+	  List_Read(simplices,j,&simp);
+	  BDS_Tet *t = m->bds->add_tet (simp->V[0]->Num,simp->V[1]->Num,simp->V[2]->Num,simp->V[3]->Num); 
+	  t->g = g;
+	  BDS_Point *n[4];
+	  t->getNodes (n);
+	  for (int K=0;K<4;K++)
+	    if (!n[K]->g) n[K]->g = g;
+	  if (!t->f1->g) t->f1->g  = g;
+	  if (!t->f2->g) t->f2->g  = g;
+	  if (!t->f3->g) t->f3->g  = g;
+	  if (!t->f4->g) t->f4->g  = g;
+	  if (!t->f1->e1->g) t->f1->e1->g  = g;
+	  if (!t->f2->e1->g) t->f2->e1->g  = g;
+	  if (!t->f3->e1->g) t->f3->e1->g  = g;
+	  if (!t->f4->e1->g) t->f4->e1->g  = g;
+	  if (!t->f1->e2->g) t->f1->e2->g  = g;
+	  if (!t->f2->e2->g) t->f2->e2->g  = g;
+	  if (!t->f3->e2->g) t->f3->e2->g  = g;
+	  if (!t->f4->e2->g) t->f4->e2->g  = g;
+	  if (!t->f1->e3->g) t->f1->e3->g  = g;
+	  if (!t->f2->e3->g) t->f2->e3->g  = g;
+	  if (!t->f3->e3->g) t->f3->e3->g  = g;
+	  if (!t->f4->e3->g) t->f4->e3->g  = g;
+
 	}
+      List_Delete(simplices);
     }
-    {
-	std::list<BDS_Triangle*>::iterator it  = m->bds_mesh->triangles.begin();
-	std::list<BDS_Triangle*>::iterator ite = m->bds_mesh->triangles.end();
-	while (it!=ite){
+  List_Delete (volumes);
+  
+}
+extern int addMeshPartition(int Num, Mesh * M);
+
+void BDS_To_Mesh_2(Mesh *m)
+{
+  Msg(STATUS2, "Moving the surface mesh in the old gmsh structure\n");
+  
+  Tree_Action(m->Vertices, Free_Vertex);  
+  Tree_Delete(m->Vertices);
+  m->Vertices = Tree_Create(sizeof(Vertex *), compareVertex);
+  
+  {
+    std::set<BDS_Point*, PointLessThan>::iterator it   = m->bds_mesh->points.begin();
+    std::set<BDS_Point*, PointLessThan>::iterator ite  = m->bds_mesh->points.end();
+    while (it != ite)
+      {
+	Vertex *vert = Create_Vertex((*it)->iD, (*it)->X,(*it)->Y,(*it)->Z, 1.0, 0.0);
+	Tree_Add (m->Vertices,&vert);
+	++it;
+      }
+  }
+  
+  
+  {
+    std::list<BDS_Edge*>::iterator it  = m->bds_mesh->edges.begin();
+    std::list<BDS_Edge*>::iterator ite = m->bds_mesh->edges.end();
+    while(it!=ite)
+      {
+	BDS_GeomEntity *g = (*it)->g;
+	if (g && g->classif_degree == 1)
+	  {
+	    Vertex *v1 = FindVertex((*it)->p1->iD, m);
+	    Vertex *v2 = FindVertex((*it)->p2->iD, m);
+	    SimplexBase *simp = Create_SimplexBase(v1,v2,NULL, NULL);
+	    Curve *c = FindCurve (g->classif_tag,m);
+	    if (c)
+	      simp->iEnt = g->classif_tag;
+	    Tree_Insert(c->Simplexes, &simp);
+	  }
+	++it;
+      }
+  }
+  {
+    std::list<BDS_Triangle*>::iterator it  = m->bds_mesh->triangles.begin();
+    std::list<BDS_Triangle*>::iterator ite = m->bds_mesh->triangles.end();
+    while (it!=ite){
+      BDS_GeomEntity *g = (*it)->g;
+      if (g && g->classif_degree == 2)
+	  {
 	    BDS_Point *nod[3];
 	    (*it)->getNodes (nod);
 	    Vertex *v1 = FindVertex(nod[0]->iD, m);
@@ -107,60 +231,100 @@ void BDS_To_Mesh_2(Mesh *m)
 	    BDS_GeomEntity *g = (*it)->g;
 	    Surface *s = FindSurface (g->classif_tag,m);
 	    if(s)
+	      {
 		simp->iEnt = g->classif_tag;
+		simp->iPart = addMeshPartition((*it)->status, m);
+	      }
 	    else
-		printf("argh\n");
-	    Tree_Add(s->SimplexesBase, &simp);
-	    ++it;
+	      printf("impossible to find surface %d\n",g->classif_tag);
+	    Tree_Add(s->Simplexes, &simp);
+	  }
+      ++it;
+    }
+  }
+  {
+    std::list<BDS_Tet*>::iterator it  = m->bds_mesh->tets.begin();
+    std::list<BDS_Tet*>::iterator ite = m->bds_mesh->tets.end();
+    while (it!=ite){
+      BDS_Point *nod[4];
+      (*it)->getNodes (nod);
+      Vertex *v1 = FindVertex(nod[0]->iD, m);
+      Vertex *v2 = FindVertex(nod[1]->iD, m);
+      Vertex *v3 = FindVertex(nod[2]->iD, m);
+      Vertex *v4 = FindVertex(nod[3]->iD, m);
+      SimplexBase *simp = Create_SimplexBase(v1,v2,v3, v4);
+      BDS_GeomEntity *g = (*it)->g;
+      Volume *v = FindVolume (g->classif_tag,m);
+      if(v)
+	{
+	  simp->iEnt = g->classif_tag;
+	  simp->iPart = addMeshPartition((*it)->status, m);
 	}
+      else
+	printf("argh\n");
+      Tree_Add(v->Simplexes, &simp);
+      ++it;
     }
+  }
     Msg(STATUS2, "Ready");
 }
+
 void BDS_To_Mesh(Mesh *m)
 {
     Tree_Action(m->Points, Free_Vertex);  
     Tree_Delete(m->Points);
+    Tree_Action(m->Volumes, Free_Volume);
     Tree_Action(m->Surfaces, Free_Surface);
     Tree_Action(m->Curves, Free_Curve);
     Tree_Delete(m->Surfaces);
     Tree_Delete(m->Curves);
+    Tree_Delete(m->Volumes);
     m->Points = Tree_Create(sizeof(Vertex *), compareVertex);
     m->Curves = Tree_Create(sizeof(Curve *), compareCurve);
     m->Surfaces = Tree_Create(sizeof(Surface *), compareSurface);
+    m->Volumes = Tree_Create(sizeof(Volume *), compareVolume);
 
     std::set<BDS_GeomEntity*,GeomLessThan>::iterator it  = m->bds->geom.begin(); 
     std::set<BDS_GeomEntity*,GeomLessThan>::iterator ite = m->bds->geom.end(); 
     
     while (it != ite)
     {
-	if ((*it)->classif_degree ==2 )
+	if ((*it)->classif_degree ==3 )
+	{
+	    Volume *_Vol = 0; 
+	    _Vol = FindVolume((*it)->classif_tag, m);
+	    if (!_Vol) 
+		_Vol = Create_Volume((*it)->classif_tag,MSH_VOLUME_DISCRETE);	
+	    Tree_Add(m->Volumes, &_Vol);	    	   
+	}
+	else if ((*it)->classif_degree ==2 )
 	{
 	    Surface *_Surf = 0; 
 	    _Surf = FindSurface((*it)->classif_tag, m);
 	    if (!_Surf) 
 		_Surf = Create_Surface((*it)->classif_tag, MSH_SURF_DISCRETE);	
-	    _Surf->bds = m->bds;
+	    //	    _Surf->bds = m->bds;
 	    End_Surface(_Surf);
-	    Tree_Add(m->Surfaces, &_Surf);
-	    
-	   
-
+	    Tree_Add(m->Surfaces, &_Surf);	    	   
 	}
 	else if ((*it)->classif_degree ==1  )
-	{
+	{ 
 	    Curve *_c = 0; 
 	    _c = FindCurve((*it)->classif_tag, m);
 	    if (!_c) 
 		_c = Create_Curve((*it)->classif_tag, MSH_SEGM_DISCRETE, 1, NULL, NULL, -1, -1, 0., 1.);	
-	    _c->bds = m->bds;
+	    //	    _c->bds = m->bds;
 	    End_Curve(_c);
 	    Tree_Add(m->Curves, &_c);
 	}
 	else if ((*it)->classif_degree == 0 )
 	{
-	    BDS_Point *p = (*it)->p;
-	    Vertex *_v = Create_Vertex(p->iD, p->X,p->Y,p->Z,1,0);	
-	    Tree_Add(m->Points, &_v);
+	  BDS_Point *p = (*it)->p;
+	  if (p)
+	    {
+	      Vertex *_v = Create_Vertex(p->iD, p->X,p->Y,p->Z,1,0);	
+	      Tree_Add(m->Points, &_v);
+	    }
 	}
 	++it;
     }
@@ -175,7 +339,7 @@ int MeshDiscreteSurface(Surface *s)
 { 
 
   const int NITER = 10;
-  if(s->bds){
+  if(THEM->bds){
     Msg(STATUS2, "Discrete Surface Mesh Generator...");
     // s->bds is the discrete surface that defines the geometry
     if(!THEM->bds_mesh){
diff --git a/Mesh/Generator.cpp b/Mesh/Generator.cpp
index 38d062f854..1d803e3a2e 100644
--- a/Mesh/Generator.cpp
+++ b/Mesh/Generator.cpp
@@ -1,4 +1,4 @@
-// $Id: Generator.cpp,v 1.70 2005-06-10 20:59:15 geuzaine Exp $
+// $Id: Generator.cpp,v 1.71 2005-09-07 14:36:45 remacle Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -27,6 +27,7 @@
 #include "Context.h"
 #include "OpenFile.h"
 #include "Views.h"
+#include "PartitionMesh.h"
 
 extern Mesh *THEM;
 extern Context_T CTX;
@@ -533,6 +534,8 @@ void mai3d(Mesh * M, int Asked)
 
   if(M->status && CTX.mesh.order == 2)
     Degre2(M->status);
+  if(M->status > 1 && CTX.mesh.nbPartitions != 1)
+    PartitionMesh ( M , CTX.mesh.nbPartitions);
 
   CTX.threads_lock = 0;
   CTX.mesh.changed = 1;
diff --git a/Mesh/Makefile b/Mesh/Makefile
index de5704face..7eb1902c4c 100644
--- a/Mesh/Makefile
+++ b/Mesh/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.94 2005-08-22 00:35:06 geuzaine Exp $
+# $Id: Makefile,v 1.95 2005-09-07 14:36:45 remacle Exp $
 #
 # Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 #
@@ -24,7 +24,7 @@ include ../variables
 LIB     = ../lib/libGmshMesh.a
 INCLUDE = -I../Numeric -I../NR -I../Common -I../DataStr -I../Geo -I../Mesh\
           -I../Graphics -I../Parser -I../Fltk -I../Triangle -I../Tetgen\
-          -I../Netgen -I../Netgen/libsrc/include  -I../Netgen/libsrc/interface -I../ANN/include
+          -I../Netgen -I../Netgen/libsrc/include  -I../Netgen/libsrc/interface -I../ANN/include -I../Metis
 CFLAGS  = ${OPTIM} ${FLAGS} ${INCLUDE}
 
 SRC = 1D_Mesh.cpp \
@@ -67,6 +67,7 @@ SRC = 1D_Mesh.cpp \
       Nurbs.cpp \
       Interpolation.cpp \
       SecondOrder.cpp \
+      PartitionMesh.cpp\
       Smoothing.cpp \
       CrossData.cpp \
       Vertex.cpp \
diff --git a/Mesh/Mesh.h b/Mesh/Mesh.h
index f369ba33d8..208d016a0f 100644
--- a/Mesh/Mesh.h
+++ b/Mesh/Mesh.h
@@ -252,7 +252,7 @@ struct _Surf{
   CylParam Cyl;
   Grid_T Grid;  // fast search grid
   ExtrudeParams *Extrude;
-  BDS_Mesh *bds;
+  //  BDS_Mesh *bds;
   DrawingColor Color;
   VertexArray *TriVertexArray;
   VertexArray *QuadVertexArray;
@@ -375,7 +375,7 @@ typedef struct{
   CircParam Circle;
   char functu[256], functv[256], functw[256];
   DrawingColor Color;
-  BDS_Mesh *bds;
+  //  BDS_Mesh *bds;
   VertexArray *LinVertexArray;
 }Curve;
 
diff --git a/Mesh/PartitionMesh.cpp b/Mesh/PartitionMesh.cpp
new file mode 100644
index 0000000000..d9c509be3b
--- /dev/null
+++ b/Mesh/PartitionMesh.cpp
@@ -0,0 +1,195 @@
+#include "Gmsh.h"
+#include "Numeric.h"
+#include "Mesh.h"
+#include "CAD.h"
+#include "Geo.h"
+#include "Create.h"
+#include "Interpolation.h"
+#include "Context.h"
+#include "BDS.h"
+#include "PartitionMesh.h"
+#include "OpenFile.h"
+#include "MinMax.h"
+
+#ifdef HAVE_METIS
+extern "C"
+{
+#include "metis.h"
+}
+#endif
+extern void Mesh_To_BDS(Mesh *m);
+extern void BDS_To_Mesh_2(Mesh *m);
+extern void BDS_To_Mesh(Mesh *m);
+
+
+void DeleteMesh(Mesh * M)
+{
+  List_T *Curves = Tree2List(M->Curves);
+  for(int i = 0; i < List_Nbr(Curves); i++) {
+    Curve *c;
+    List_Read(Curves, i, &c);
+    Tree_Action(c->Simplexes, Free_SimplexBase);
+    Tree_Delete(c->Simplexes);
+    c->Simplexes = Tree_Create(sizeof(SimplexBase *), compareSimplex);
+  }
+  List_T *Surfaces = Tree2List(M->Surfaces);
+  for(int i = 0; i < List_Nbr(Surfaces); i++){
+    Surface *s;
+    List_Read(Surfaces, i, &s);
+    Tree_Action(s->Simplexes, Free_SimplexBase);
+    Tree_Delete(s->Simplexes);
+    s->Simplexes = Tree_Create(sizeof(SimplexBase *), compareSimplex);
+  }
+  List_Delete(Surfaces);
+  
+  List_T *Volumes = Tree2List(M->Volumes);
+  for(int i = 0; i < List_Nbr(Volumes); i++){
+    Volume *v;
+    List_Read(Volumes, i, &v);
+    Tree_Action(v->Simplexes, Free_SimplexBase);
+    Tree_Delete(v->Simplexes);
+    v->Simplexes = Tree_Create(sizeof(SimplexBase *), compareSimplex);
+  }
+  List_Delete(Volumes);
+}
+
+
+void PartitionMesh ( Mesh *M , int NP)
+{
+
+  printf("moving the mesh to BDS\n");
+  Mesh_To_BDS (M);
+  BDS_Mesh *m = M->bds;
+  printf("partitioning\n");
+  PartitionMesh (m,NP);
+  printf("Moving back to the old data str\n");
+  DeleteMesh (M);// BDS_To_Mesh(M);
+  M->bds_mesh = new BDS_Mesh (*M->bds);
+  BDS_To_Mesh_2(M);
+  delete M->bds;
+  delete M->bds_mesh;
+  M->bds = 0;
+  M->bds_mesh = 0;
+  SetBoundingBox();
+}
+
+void PartitionMesh ( BDS_Mesh *m , int NP)
+{
+
+#ifdef HAVE_METIS
+  // NN = number of nodes of the graph
+  int dim = (m->tets.size() == 0)?2:3;
+  int NN = (dim == 2)? m->triangles.size() : m->tets.size() ;
+
+  printf ("%d nodes in the graph\n",NN);
+  
+  int *partitionVector = new int[NN];
+  int *xadj   = new int[NN+2];
+
+  int totCount = 0;
+
+  std::list<BDS_Triangle*>::iterator it2 = m->triangles.begin();
+  std::list<BDS_Tet*>::iterator it3 = m->tets.begin();
+
+  xadj[0] = 0;
+  for(int i=0;i<NN;i++)
+    {
+      int nbAdj = 0;
+      if (dim == 2)
+	{
+	  BDS_Triangle *t = *it2;
+	  t->status = i;
+	  ++it2;
+	  nbAdj = (t->e1->numfaces() + t->e2->numfaces() + t->e3->numfaces() - 3);
+	  totCount += nbAdj;
+	}
+      else if (dim == 3)
+	{
+	  BDS_Tet *t = *it3;
+	  t->status = i;
+	  ++it3;
+	  nbAdj =(t->f1->numtets() + t->f2->numtets() + t->f3->numtets() + t->f4->numtets() - 4); 
+	  totCount += nbAdj;
+	}
+      xadj[i+1] = xadj[i] + nbAdj;
+    }
+
+  printf ("Tot Count %d \n",totCount);
+
+  it2 = m->triangles.begin();
+  it3 = m->tets.begin();
+
+  int *adjncy = new int[totCount+1];    
+
+  int count = 0;
+
+  for(int i=0;i<NN;i++)
+    {
+      if (dim == 2)
+	{
+	  BDS_Triangle *t = *it2;
+	  for (int j=0;j<t->e1->numfaces();j++)
+	    {
+	      BDS_Triangle *f = t->e1->faces(j);
+	      if (f != t) adjncy[count++] = f->status;
+	    }
+	  for (int j=0;j<t->e2->numfaces();j++)
+	    {
+	      BDS_Triangle *f = t->e2->faces(j);
+	      if (f != t) adjncy[count++] = f->status;
+	    }
+	  for (int j=0;j<t->e3->numfaces();j++)
+	    {
+	      BDS_Triangle *f = t->e3->faces(j);
+	      if (f != t) adjncy[count++] = f->status;
+	    }
+	  ++it2;
+	}
+      else if (dim == 3)
+	{
+	  BDS_Tet *t = *it3;
+	  BDS_Tet *o = t->f1->opposite_tet (t);
+	  if (o) adjncy[count++] = o->status;
+	  o = t->f2->opposite_tet (t);
+	  if (o) adjncy[count++] = o->status;
+	  o = t->f3->opposite_tet (t);
+	  if (o) adjncy[count++] = o->status;
+	  o = t->f4->opposite_tet (t);
+	  if (o) adjncy[count++] = o->status;
+	  ++it3;
+	}
+    }
+
+  int wgtflag = 0;
+  int numflag = 0;
+  int options[4];
+  options[0] = 0;
+  int edgecut;
+  METIS_PartGraphRecursive(&NN,xadj,adjncy,0,0,&wgtflag,
+			   &numflag,&NP,options,&edgecut,
+			   partitionVector); 
+  delete [] xadj;
+  delete [] adjncy;
+
+  it2 = m->triangles.begin();
+  it3 = m->tets.begin();
+
+  for(int i=0;i<NN;i++)
+    {
+      if (dim == 2)
+	{
+	  BDS_Triangle *t = *it2;
+	  t->status = partitionVector[i];
+	  ++it2;
+	}
+      else if (dim == 3)
+	{
+	  BDS_Tet *t = *it3;
+	  t->status = partitionVector[i];
+	  ++it3;
+	}
+    }
+
+  delete [] partitionVector;
+#endif
+}
diff --git a/Mesh/PartitionMesh.h b/Mesh/PartitionMesh.h
new file mode 100644
index 0000000000..6e22359f88
--- /dev/null
+++ b/Mesh/PartitionMesh.h
@@ -0,0 +1,5 @@
+#ifndef _PARTITION_MESH_GMSH__
+#define _PARTITION_MESH_GMSH__
+void PartitionMesh ( BDS_Mesh *M , int NP);
+void PartitionMesh ( Mesh *M , int NP);
+#endif
diff --git a/Mesh/Read_Mesh.cpp b/Mesh/Read_Mesh.cpp
index 334b3d0f83..e2178c2803 100644
--- a/Mesh/Read_Mesh.cpp
+++ b/Mesh/Read_Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Read_Mesh.cpp,v 1.93 2005-06-20 17:02:46 geuzaine Exp $
+// $Id: Read_Mesh.cpp,v 1.94 2005-09-07 14:36:45 remacle Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -28,6 +28,7 @@
 #include "MinMax.h"
 #include "Numeric.h"
 #include "Context.h"
+#include "PartitionMesh.h"
 
 extern Context_T CTX;
 
@@ -907,6 +908,7 @@ void Read_Mesh_SMS(Mesh * m, FILE * in)
 }
 
 // Public Read_Mesh routine
+extern  void Mesh_To_BDS(Mesh *m);
 
 void Read_Mesh(Mesh * M, FILE * fp, char *filename, int type)
 {
@@ -928,4 +930,7 @@ void Read_Mesh(Mesh * M, FILE * fp, char *filename, int type)
     Msg(INFO, "Read mesh file '%s'", filename);
     Msg(STATUS2N, "Read '%s'", filename);
   }
+  if (CTX.mesh.nbPartitions != 1)
+    PartitionMesh ( M , CTX.mesh.nbPartitions);
+  //  Mesh_To_BDS(M);
 }
diff --git a/Metis/Doc/manual.ps b/Metis/Doc/manual.ps
new file mode 100644
index 0000000000..d77abe5658
--- /dev/null
+++ b/Metis/Doc/manual.ps
@@ -0,0 +1,16447 @@
+%!PS-Adobe-2.0
+%%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software
+%%Title: manual.dvi
+%%Pages: 44
+%%PageOrder: Ascend
+%%BoundingBox: 0 0 612 792
+%%DocumentFonts: Helvetica-Bold MTSYN AvantGarde-Demi Helvetica
+%%+ Times-Roman Times-Italic Times-Bold Helvetica-Narrow-Bold
+%%+ Helvetica-Narrow ZapfDingbats RMTMI Courier Times-BoldItalic
+%%+ Helvetica-Narrow-Oblique Courier-Oblique MTEX
+%%DocumentPaperSizes: Letter
+%%EndComments
+%DVIPSCommandLine: dvips -o manual.ps manual
+%DVIPSParameters: dpi=600, comments removed
+%DVIPSSource:  TeX output 1998.09.20:1257
+%%BeginProcSet: tex.pro
+<< /Duplex true >> setpagedevice  % GK
+/TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N
+/X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72
+mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1}
+ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale
+isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div
+hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul
+TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if}
+forall round exch round exch]setmatrix}N /@landscape{/isls true N}B
+/@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B
+/FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{
+/nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N
+string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N
+end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{
+/sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0]
+N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup
+length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{
+128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub
+get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data
+dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N
+/rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup
+/base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx
+0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff
+setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff
+.1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]}
+if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup
+length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{
+cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin
+0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul
+add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict
+/eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook
+known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X
+/IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for
+65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0
+0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V
+{}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7
+getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false}
+ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false
+RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1
+false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform
+round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg
+rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail
+{dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M}
+B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{
+4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{
+p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p
+a}B /bos{/SS save N}B /eos{SS restore}B end
+%%EndProcSet
+%%BeginProcSet: psfrag.pro
+userdict begin
+/PSfragLib 90 dict def
+/PSfragDict 6 dict def
+/PSfrag { PSfragLib begin load exec end } bind def
+end
+PSfragLib begin
+/RO /readonly      load def
+/CP /currentpoint  load def
+/CM /currentmatrix load def
+/B { bind RO def } bind def
+/X { exch def } B
+/MD { { X } forall } B
+/OE { end exec PSfragLib begin } B
+/tstr 8 string def
+/islev2 { languagelevel } stopped { false } { 2 ge } ifelse def
+[ /tM /srcM /dstM /dM /idM /srcFM /dstFM ] { matrix def } forall
+dM defaultmatrix RO idM invertmatrix RO pop
+srcFM identmatrix pop
+/Hide { gsave { CP } stopped not newpath clip { moveto } if } B
+/Unhide { { CP } stopped not grestore { moveto } if } B
+/setrepl islev2 {{ /glob currentglobal def true setglobal array astore
+                   globaldict exch /PSfrags exch put glob setglobal }}
+                {{ array astore /PSfrags X }} ifelse B
+/getrepl islev2 {{ globaldict /PSfrags get aload length }}
+                {{ PSfrags aload length }} ifelse B
+/convert {
+   /src X src length string
+   /c 0 def src length {
+      dup c src c get dup 32 lt { pop 32 } if put /c c 1 add def
+   } repeat
+} B
+/Begin {
+    /saver save def
+    srcFM exch 3 exch put
+    0 ne /debugMode X 0 setrepl
+    dup /S exch dict def { S 3 1 roll exch convert exch put } repeat
+    srcM CM dup invertmatrix pop
+    mark { currentdict { end } stopped { pop exit } if } loop
+    PSfragDict counttomark { begin } repeat pop
+} B
+/End {
+    mark { currentdict end dup PSfragDict eq { pop exit } if } loop
+    counttomark { begin } repeat pop
+    getrepl saver restore
+    7 idiv dup /S exch dict def {
+        6 array astore /mtrx X tstr cvs /K X
+        S K [ S K known { S K get aload pop } if mtrx ] put
+    } repeat
+} B
+/Place {
+    tstr cvs /K X
+    S K known {
+        bind /proc X tM CM pop
+        CP /cY X /cX X
+        0 0 transform idtransform neg /aY X neg /aX X
+        S K get dup length /maxiter X
+        /iter 1 def {
+            iter maxiter ne { /saver save def } if
+            tM setmatrix aX aY translate
+            [ exch aload pop idtransform ] concat
+            cX neg cY neg translate cX cY moveto
+            /proc load OE
+            iter maxiter ne { saver restore /iter iter 1 add def } if
+        } forall
+        /noXY { CP /cY X /cX X } stopped def
+        tM setmatrix noXY { newpath } { cX cY moveto } ifelse
+    } {
+        Hide OE Unhide
+    } ifelse
+} B
+/normalize {
+    2 index dup mul 2 index dup mul add sqrt div
+    dup 4 -1 roll exch mul 3 1 roll mul
+} B
+/replace {
+    aload pop MD
+    CP /bY X /lX X gsave initmatrix
+    str stringwidth abs exch abs add dup 0 eq
+        { pop } { 360 exch div dup scale } ifelse
+    lX neg bY neg translate newpath lX bY moveto
+    str { /ch X ( ) dup 0 ch put false charpath ch Kproc } forall
+    flattenpath pathbbox [ /uY /uX /lY /lX ] MD
+    CP grestore moveto
+    currentfont /FontMatrix get dstFM copy dup
+    0 get 0 lt { uX lX /uX X /lX X } if
+    3 get 0 lt { uY lY /uY X /lY X } if
+    /cX uX lX add 0.5 mul def
+    /cY uY lY add 0.5 mul def
+    debugMode { gsave 0 setgray 1 setlinewidth
+        lX lY moveto lX uY lineto uX uY lineto uX lY lineto closepath
+        lX bY moveto uX bY lineto lX cY moveto uX cY lineto
+        cX lY moveto cX uY lineto stroke
+    grestore } if
+    dstFM dup invertmatrix dstM CM srcM
+    2 { dstM concatmatrix } repeat pop
+    getrepl /temp X
+        S str convert get {
+            aload pop [ /rot /scl /loc /K ] MD
+            /aX cX def /aY cY def
+            loc {
+                dup 66  eq { /aY bY def } { % B
+                dup 98  eq { /aY lY def } { % b
+                dup 108 eq { /aX lX def } { % l
+                dup 114 eq { /aX uX def } { % r
+                dup 116 eq { /aY uY def }   % t
+                if } ifelse } ifelse } ifelse } ifelse pop
+            } forall
+            K srcFM rot tM rotate dstM
+            2 { tM concatmatrix } repeat aload pop pop pop
+            2 { scl normalize 4 2 roll } repeat
+            aX aY transform
+            /temp temp 7 add def
+        } forall
+    temp setrepl
+} B
+/Rif {
+    S 3 index convert known { pop replace } { exch pop OE } ifelse
+} B
+/XA { bind [ /Kproc /str } B /XC { ] 2 array astore def } B
+/xs   { pop } XA XC
+/xks  { /kern load OE } XA /kern XC
+/xas  { pop ax ay rmoveto } XA /ay /ax XC
+/xws  { c eq { cx cy rmoveto } if } XA /c /cy /cx XC
+/xaws { ax ay rmoveto c eq { cx cy rmoveto } if }
+    XA /ay /ax /c /cy /cx XC
+/raws { xaws { awidthshow } Rif } B
+/rws  { xws { widthshow } Rif } B
+/rks  { xks { kshow } Rif } B
+/ras  { xas { ashow } Rif } B
+/rs   { xs { show } Rif } B
+/rrs { getrepl dup 2 add -1 roll restore setrepl } B
+PSfragDict begin
+islev2 not { /restore { /rrs PSfrag } B } if
+/show       { /rs   PSfrag } B
+/kshow      { /rks  PSfrag } B
+/ashow      { /ras  PSfrag } B
+/widthshow  { /rws  PSfrag } B
+/awidthshow { /raws PSfrag } B
+end PSfragDict RO pop
+end
+
+%%EndProcSet
+%%BeginFont: Helvetica-Bold
+% @@psencodingfile@{
+%   author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry",
+%   version = "0.6",
+%   date = "22 June 1996",
+%   filename = "8r.enc",
+%   email = "kb@@mail.tug.org",
+%   address = "135 Center Hill Rd. // Plymouth, MA 02360",
+%   codetable = "ISO/ASCII",
+%   checksum = "119     662    4424",
+%   docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX."
+% @}
+% 
+% Idea is to have all the characters normally included in Type 1 fonts
+% available for typesetting. This is effectively the characters in Adobe
+% Standard Encoding + ISO Latin 1 + extra characters from Lucida.
+% 
+% Character code assignments were made as follows:
+% 
+% (1) the Windows ANSI characters are almost all in their Windows ANSI
+% positions, because some Windows users cannot easily reencode the
+% fonts, and it makes no difference on other systems. The only Windows
+% ANSI characters not available are those that make no sense for
+% typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen
+% (173). quotesingle and grave are moved just because it's such an
+% irritation not having them in TeX positions.
+% 
+% (2) Remaining characters are assigned arbitrarily to the lower part
+% of the range, avoiding 0, 10 and 13 in case we meet dumb software.
+% 
+% (3) Y&Y Lucida Bright includes some extra text characters; in the
+% hopes that other PostScript fonts, perhaps created for public
+% consumption, will include them, they are included starting at 0x12.
+% 
+% (4) Remaining positions left undefined are for use in (hopefully)
+% upward-compatible revisions, if someday more characters are generally
+% available.
+% 
+% (5) hyphen appears twice for compatibility with both ASCII and Windows.
+% 
+/TeXBase1Encoding [
+% 0x00 (encoded characters from Adobe Standard not in Windows 3.1)
+  /.notdef /dotaccent /fi /fl
+  /fraction /hungarumlaut /Lslash /lslash
+  /ogonek /ring /.notdef
+  /breve /minus /.notdef 
+% These are the only two remaining unencoded characters, so may as
+% well include them.
+  /Zcaron /zcaron 
+% 0x10
+ /caron /dotlessi 
+% (unusual TeX characters available in, e.g., Lucida Bright)
+ /dotlessj /ff /ffi /ffl 
+ /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef
+ % very contentious; it's so painful not having quoteleft and quoteright
+ % at 96 and 145 that we move the things normally found there down to here.
+ /grave /quotesingle 
+% 0x20 (ASCII begins)
+ /space /exclam /quotedbl /numbersign
+ /dollar /percent /ampersand /quoteright
+ /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash
+% 0x30
+ /zero /one /two /three /four /five /six /seven
+ /eight /nine /colon /semicolon /less /equal /greater /question
+% 0x40
+ /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O
+% 0x50
+ /P /Q /R /S /T /U /V /W
+ /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+% 0x60
+ /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o
+% 0x70
+ /p /q /r /s /t /u /v /w
+ /x /y /z /braceleft /bar /braceright /asciitilde
+ /.notdef % rubout; ASCII ends
+% 0x80
+ /.notdef /.notdef /quotesinglbase /florin
+ /quotedblbase /ellipsis /dagger /daggerdbl
+ /circumflex /perthousand /Scaron /guilsinglleft
+ /OE /.notdef /.notdef /.notdef
+% 0x90
+ /.notdef /.notdef /.notdef /quotedblleft
+ /quotedblright /bullet /endash /emdash
+ /tilde /trademark /scaron /guilsinglright
+ /oe /.notdef /.notdef /Ydieresis
+% 0xA0
+ /.notdef % nobreakspace
+ /exclamdown /cent /sterling
+ /currency /yen /brokenbar /section
+ /dieresis /copyright /ordfeminine /guillemotleft
+ /logicalnot
+ /hyphen % Y&Y (also at 45); Windows' softhyphen
+ /registered
+ /macron
+% 0xD0
+ /degree /plusminus /twosuperior /threesuperior
+ /acute /mu /paragraph /periodcentered
+ /cedilla /onesuperior /ordmasculine /guillemotright
+ /onequarter /onehalf /threequarters /questiondown
+% 0xC0
+ /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla
+ /Egrave /Eacute /Ecircumflex /Edieresis
+ /Igrave /Iacute /Icircumflex /Idieresis
+% 0xD0
+ /Eth /Ntilde /Ograve /Oacute
+ /Ocircumflex /Otilde /Odieresis /multiply
+ /Oslash /Ugrave /Uacute /Ucircumflex
+ /Udieresis /Yacute /Thorn /germandbls
+% 0xE0
+ /agrave /aacute /acircumflex /atilde
+ /adieresis /aring /ae /ccedilla
+ /egrave /eacute /ecircumflex /edieresis
+ /igrave /iacute /icircumflex /idieresis
+% 0xF0
+ /eth /ntilde /ograve /oacute
+ /ocircumflex /otilde /odieresis /divide
+ /oslash /ugrave /uacute /ucircumflex
+ /udieresis /yacute /thorn /ydieresis
+] def
+%%EndFont
+%%BeginFont: MTSYN
+
+% MathTime fonts were designed by Michael Spivak.
+% Copyright (c) 1996 Publish or Perish, Inc.
+% Hinting Copyright (c) 1996 Y&Y, Inc.
+% MathTime is a registered trademark of Publish or Perish, Inc.
+
+11 dict begin
+/FontInfo 9 dict dup begin
+/version (1.000) readonly def
+/Notice (Copyright (c) 1992-1996 Publish or Perish and Y&Y, Inc.) readonly def
+/FullName (MTSYN) readonly def
+/FamilyName (MathTime) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/FontName /MTSYN def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 161 /minus put
+dup 162 /periodcentered put
+dup 163 /multiply put
+dup 164 /asteriskmath put
+dup 165 /divide put
+dup 166 /diamondmath put
+dup 167 /plusminus put
+dup 168 /minusplus put
+dup 169 /circleplus put
+dup 170 /circleminus put
+dup 173 /circlemultiply put
+dup 174 /circledivide put
+dup 175 /circledot put
+dup 176 /circlecopyrt put
+dup 177 /openbullet put
+dup 178 /bullet put
+dup 179 /equivasymptotic put
+dup 180 /equivalence put
+dup 181 /reflexsubset put
+dup 182 /reflexsuperset put
+dup 183 /lessequal put
+dup 184 /greaterequal put
+dup 185 /precedesequal put
+dup 186 /followsequal put
+dup 187 /similar put
+dup 188 /approxequal put
+dup 189 /propersubset put
+dup 190 /propersuperset put
+dup 191 /lessmuch put
+dup 192 /greatermuch put
+dup 193 /precedes put
+dup 194 /follows put
+dup 195 /arrowleft put
+dup 196 /spade put
+dup 128 /arrowleft put
+dup 0 /minus put
+dup 1 /periodcentered put
+dup 2 /multiply put
+dup 3 /asteriskmath put
+dup 4 /divide put
+dup 5 /diamondmath put
+dup 6 /plusminus put
+dup 7 /minusplus put
+dup 8 /circleplus put
+dup 9 /circleminus put
+dup 10 /circlemultiply put
+dup 11 /circledivide put
+dup 12 /circledot put
+dup 13 /circlecopyrt put
+dup 14 /openbullet put
+dup 15 /bullet put
+dup 16 /equivasymptotic put
+dup 17 /equivalence put
+dup 18 /reflexsubset put
+dup 19 /reflexsuperset put
+dup 20 /lessequal put
+dup 21 /greaterequal put
+dup 22 /precedesequal put
+dup 23 /followsequal put
+dup 24 /similar put
+dup 25 /approxequal put
+dup 26 /propersubset put
+dup 27 /propersuperset put
+dup 28 /lessmuch put
+dup 29 /greatermuch put
+dup 30 /precedes put
+dup 31 /follows put
+dup 32 /arrowleft put
+dup 33 /arrowright put
+dup 34 /arrowup put
+dup 35 /arrowdown put
+dup 36 /arrowboth put
+dup 37 /arrownortheast put
+dup 38 /arrowsoutheast put
+dup 39 /similarequal put
+dup 40 /arrowdblleft put
+dup 41 /arrowdblright put
+dup 42 /arrowdblup put
+dup 43 /arrowdbldown put
+dup 44 /arrowdblboth put
+dup 45 /arrownorthwest put
+dup 46 /arrowsouthwest put
+dup 47 /proportional put
+dup 48 /prime put
+dup 49 /infinity put
+dup 50 /element put
+dup 51 /owner put
+dup 52 /triangle put
+dup 53 /triangleinv put
+dup 54 /negationslash put
+dup 55 /mapsto put
+dup 56 /universal put
+dup 57 /existential put
+dup 58 /logicalnot put
+dup 59 /emptyset put
+dup 60 /Rfractur put
+dup 61 /Ifractur put
+dup 62 /latticetop put
+dup 63 /perpendicular put
+dup 64 /aleph put
+dup 65 /tie put
+dup 66 /openbullet1 put
+dup 67 /plus put
+dup 68 /equal put
+dup 69 /vector put
+dup 70 /triangleright put
+dup 71 /triangleleft put
+dup 72 /equal1 put
+dup 73 /semicolon put
+dup 74 /grave put
+dup 75 /acute put
+dup 76 /caron put
+dup 77 /breve put
+dup 78 /macron put
+dup 79 /circumflex put
+dup 80 /dotaccent put
+dup 81 /tilde put
+dup 82 /dieresis put
+dup 83 /overbar put
+dup 84 /bracketleft put
+dup 85 /bracketright put
+dup 86 /colon put
+dup 87 /exclam put
+dup 88 /setminus put
+dup 89 /cupproduct put
+dup 90 /capproduct put
+dup 91 /union put
+dup 92 /intersection put
+dup 93 /unionmulti put
+dup 94 /logicaland put
+dup 95 /logicalor put
+dup 96 /turnstileleft put
+dup 97 /turnstileright put
+dup 98 /floorleft put
+dup 99 /floorright put
+dup 100 /ceilingleft put
+dup 101 /ceilingright put
+dup 102 /braceleft put
+dup 103 /braceright put
+dup 104 /angbracketleft put
+dup 105 /angbracketright put
+dup 106 /bar put
+dup 107 /bardbl put
+dup 108 /arrowbothv put
+dup 109 /arrowdblbothv put
+dup 110 /backslash put
+dup 111 /wreathproduct put
+dup 112 /radical put
+dup 113 /coproduct put
+dup 114 /nabla put
+dup 115 /integral put
+dup 116 /unionsq put
+dup 117 /intersectionsq put
+dup 118 /subsetsqequal put
+dup 119 /supersetsqequal put
+dup 120 /club1 put
+dup 121 /club2 put
+dup 122 /spade1 put
+dup 123 /spade2 put
+dup 124 /club put
+dup 125 /diamond put
+dup 126 /heart put
+dup 127 /spade put
+dup 132 /radical1 put
+dup 160 /space put
+readonly def
+/FontBBox{0 -954 1043 900}readonly def
+/UniqueID 5087393 def
+currentdict end
+currentfile eexec
+80347982AB3942D930E069A70D0D48311E252234D51741E18DB3A68E8AD1024229E5817A10E796
+A78D2C7F7C1F50961B9A57AA604C9F821DBF5A9295197BC66631678D7D2C7E1F8F2151CE0C29EF
+CE46270570F4301C5DAD1B38884732E53DAD05DFC36B020E726CA575F71F04ABF2B49E1F1D6D2A
+08A477658CA9A48F1C8CCE14382F0A42201DE56E2821EE2B0E91A818B1B753D810EC2428DAE515
+3B66AF66A6CBCBA4DB2BF926E909644DB41326E327493B2750168D128A100FE56C76B17C16F9CE
+939588D19C6E9CDA7CB062196E66E38E537670953934FFC63663C7146A12277D8F7C13B563981D
+696E0ABE4478EABEBA753024EBDF3EE17F2613DF08C9228159906A48DDEED6212332EF96023E5C
+73EA55AAC6A2B938138EC26B4732C11E8FED889257E9D4F2002935585D9AA2265929948E37BAB7
+ADF12F1A22B3C68D09A6B6C4E14B1470ECF0874D92D964CFBB8E2A0E4CBD1A114CC05BBDEE4699
+A576AB8C0BD8499B166E9E60B21F45561279F6474BB497E3D55DD09A26264FFA6E8D9F228E894C
+456756D321BB5D5932C5BBCD39EB95F5B7D4DC2DA25D6773EA6BF8B758972BEF890ED520777E90
+B017BB4F0F1A7076DA33C972773E8ECFDF76B347FE529109A1EA0D91B80161C32E4DFB08EF07F2
+3680182631BAF1BEA4A5B9E505311402D9263290E3CF4409B44EDFE28038A0F2101424A9AA4CE8
+3A902FAAA4EE6DA88833898CD9EFB74A321458332CC9A62C93501CD1EB799C6DA44F94C61ADA58
+024D0CED31CD07BA36A70D986AAAD1D3B9C04D6ACBA7ECAE982A8712BA24B26BC4BF9B042C6FCC
+9BF7D3404804E72D2B93FD4F56771495070AA0FD181C35CC11CF251BE8DEA12600643F2B79D09A
+A1BCF2636F70EDF1F7E0E434DF83B888598ECE0100492A48645305B4BB8BF16CC994ABDAF88EE7
+CA62FA459E421580531F5BDFD3BD83467260F184AFA17ABFF39208581863ACD6632867C05EC9C1
+1A910E396F09359713C5B37AE855D3A2FF8657FB89CAD579EB1BAA0979EB227202E44306B7C89D
+6B32C41795F994B293A6BAF7DF640C3F68CBA7674E695121892C8DF86D2C12158D6628BA8643AF
+6C51D4241FE528EEAC4653FE8A99CC319F7B1351325AA04461810D536E61F220D309E0BF6A55EB
+EB2D1605B65B5550F6DF814FC3E80ADD43E595DFD4C947C4126521D740199C6F98826DE413EDA3
+0F7D91CAF64987B9519B8329E91644DB1EABD71A9BFF215C4691D38024D081D4F769B5CD39ECA1
+67E006B69D797D17D6B9623B7A86AFE5C6E7528FD6D2338146CFA3F34D31A526CA389AC1AF9D72
+83931EA406E45980A3A56107885A74F2FFC195F0A44AA3747B7A4F2B35E7ABE1C949ABEC591E58
+50B654494A5081D0752358A7D90814CE9531D9857C3B127EDD77C3ED727BD0BE7A8143701624AD
+DF7C7D84D37CDC05E3E97357D51E3CA329EC76C1924D84091FD864C03D6681136DBC5A81B93FC5
+81BCB2AE6BC9EAAF56BD9A4B7EBFC9A87B6828856BF2A0FD3D744755C02404518AA492077EDF15
+27A71C3A07A751EA11D80E1CA421EAC1F10E29DC40327C0E0F1F6E171E2CBCA87CEE30BA697735
+1361E221A57879D8E1AA7A59F69714389D2C861DF37439BC8713D1771269DA938C8712BB8D868F
+D89084A7A8D843AA906C85D1F7EAFEC4DCCE5A8AB542C082B6DCD262C4CA3DA711CA55F28FFEA8
+48E8CCF3BB482CE7ED0D0F1476DBC00704E58207E89AFF346B09DA6000AEA0E6DF562AEC72B822
+6F1C0A9FD7D2378B0CDB7B9A6D51CD54E90051D47F382449D5D23CF6D176913E82474C08F6E4E3
+4577374CE08643CC099DB37FAF73F9D768C3AD7FB7E632FB2EBC0DDDFE6233B00AB0B3E17E0C81
+6093F5D0BCD6A575E587A677670BF7D7250689C7BCDEC50559B82AC0B3B0633638EC5D98AD125D
+A00409EEF477825168094F02D3898DCF2C2EC2BBBD4E1BA25E5A4B8E15A6DEDE6005EB2B36EC46
+5B2FEF9532ADF7D35CA2EAEB5F8780AE3D7C09AF01A444FC709E3B2954D504F53D52050F17CAFC
+9F57E64535C8FE2213E72DF4A9E8A38F4D4AABAC1FFD1145F5AE667C8A01CFD78DC45DDACB09F2
+7BBD5D23201AC648891138787900E880D512875E6CA58CC884933B164B53B4D288FF85B9B94B03
+EDD9D577670F4842870603BD0F6DA5C01613B9A8D43CD874D4FC67DA17BD49320FED903E5B5787
+9FC5795689C812D74BAE79B680544E8C6482BA00FD3581A366F61345B6936493B2BC8450AFB363
+3FD514D71ED865B791F73CE883AA7A86368EBDC60FE713081D2C0AB4057260AF002E5D298EE067
+1F04C33B7BA068B476BAE2DA48C383663A4921C02FFABFD5915125BAF1CBA2E26014CB589D6710
+A4E722B2C642786DD2B783A4347FC66E0158F699BDB8BD2D037FDBBC89580597C87EDC84C9412F
+6BB07FF97A9EAE3DA693BB8E576D3849D244FF89F24A9A5809120A76037A6085BBCC89D096EF93
+DDF6B33D3969A28A0E33777774499D00595B4C4FB6BEB5DB1CB20AC0628CE23BD0211708801129
+42830CC65438739442C1101F09EA0FBF2686B6317CF0269278B451B03090E9604503A6B9D3798C
+5F1C925BFBFCEB527C1262B8CD9C0F18A4A254171BB0BF44FA6BF978DE049096B8B39670EF6AE5
+790F6435F0C5509E1FF24334085429E3B64B48F3F91077F8CA3C21B0877ABE2EA0779736ABB492
+D050CD016D127FA3EDD0FC7413E7E4439A122C37E009B8EC4F958921F0D8501F6AFBA85A2FD614
+F9FF40AE81D821AAF6208C1CAD31ACE6EF57F7BB10F21D81BE5C2EC55730425770C35DE27F6630
+641AF6D39FE9B2610C965C867C001ABEF1AD4D4C7D262D602719E5DBBC327E609FF1F4982006B7
+C45681AE3EBAFE8AA4EF1DCCA0F37D3FF2CD55B1609B5A654B6A2890A53A9CE022BF9965720959
+0D14EB79D6E380ED246B1A632D8FA7795D22184917B063B58E9E2D87DE7655EFDC207DBAA36A2B
+FF92BA88C5919FF06D085FB9FD0AB19F01F4C3181D9D82B88344C63A75401862F92282E49241CA
+CC5C0AC86C72A5D75BE7D819940F21C8F6477BA35C5EB5DE7E244CB12C25ADE420823E8933FCB2
+407AAB99AD7A7B56DE0A21A3D7FBBD04C90C58A3504A9B5ECEAD94043A16EE8E766E550F6D0947
+30699B58FF84366C47BC2D2A99AEE14499E86A236A2344DAD2263C09C6F982AA252A4180880D9F
+D7E90C16FFAA55A36EBED8A1E23E4792B3C7EB8EA63F60A08075F0E4BFB0379CE0DC4B7FB5C113
+CBD837F25C0B6F2CD5FE795E300F1245C99C842EE44DE3B8A352841DFA72B9CD6BECDBB51E7A95
+6470E5F081105AB88CC28DFFB66A85D0C75D86F3D7F34C6AA8B0DFFC8B9FC516602116FDD4858E
+7DE3AC948F05877B83B7ED7FFDB0B69DE973127B626973AF1CAB5DB213AAFD9C6CA273D5485DC3
+90225252E0DA375406D26011CAC71A7B0C6B3372D2F1C9DABAA5A31C7F8D040B2E099FD7429824
+36C64D34E053C3DAE86B94E16EDCA81ECA39395F8BB552CB2DB50C7F2A9ABD3710C87017248D6A
+1EB7416CE5EDAE99EC4270FEFF0DF173A7C18C13A75BE389A4A5412F69C4EE52E411CFE3716425
+DEAF057C40E0F9B2008E69BED121CC9EC4471A210D71823E8EBA1FAF6D88C1F8B2DB2375FF469B
+E556CC6208EDF9AF791AC411E80D74BC6F395AD859BE71805E908A0047A12F958A4022FD1EBD48
+37087F283BA1F1B623A584A390663DA5548E43C314D2486E3831F8494C789AB4C636B78482E830
+662A15FC0CA3030C25A481740DB53C4200EF8206F0E097740F3D031544530FA10558CDABEADA04
+6EB00F7C807C73AAD1E3C60D9057A03CD8DC22946E637BB60A776A65164D24BF91A0C9FBC19DBF
+BF3B8A0FFA91F438F3422595161200360D3321892D0192AC05BC7A74E52506A620A810AC0C7A5A
+C13FE0BBB2A4B2090D1778595191FE755C48148BAEA2AB58DD6CA75F6E4028C9C836E6216C9090
+3ED51C1C33F7B5C8FFFE3E2DE23B0B25AB93FD935C408C678BDA7D623B1861B230BC8F5D21B8EB
+AF6A2DC806FDFB21D662993F4DE3A85284BDE964FE7899B541BB17F4C4808BCFABC3A746A2F330
+77AEC41DB37637F4B5105EF1D58C64AC52CC86BF963F875919B3FD33F12A7147B3437B6894CF91
+6D6D3972830B4F849DC2E06CA9444D0EAC059C3B20705B77810C916554C94C7BB36070783A3757
+4CC482215D03C436D2AB7A1B705BC5C2939172839973E4D89D5F57D71A5D1297EBCA20A2947B15
+90907D172FCC7BB1488B1C663A06B91C139DA00AB40B16D933172C3EA66601AA0CA05828B35FF2
+5326184555BE5D36956F04A1BCE10F90D2DF77263E1AA8D79859BEE17780C64187224E1739FA8A
+4AC464D07EF68101480E0925E7EE98FD8C0CF5AAF30F771383366BAEBC03D5636C1A1A81D92921
+05B67FDC74576EF3C2D4089BC68657B15733898A0B26B54D9BE19CB9990CB054E9BBB5BCD4BE87
+ADD1629A0D436884CB3E5CAF84C55093278393568251B4450EA719A857379E027FD259028CA68D
+313F997616D51FA918B91DBCE6213FC3ECACD4585BAD71068F27243CDF7708F46EAE16A7F67913
+D201387A98776EA8B0C5E459E52B13754C191E27B3BBF8CED1D54A72DFC6D7EB1578AE9826441C
+B476E54856E2F9BAC9F10E0B5FACEFBD3250F232F611666F5212CBA21862BA9060523BB0B44002
+F2FB29B038332C893EE3313C62AAEB1FF0DADC860AD1F179489C06C9BB96D843CEABF5196E7C1A
+57DFF4502BA71B2B711653BE32A7003D6EE97209B2FB6C4F22B8DB8094166A28B993B6246B792E
+D65DD84000F0D4A547B134E46BD4E495B2763C48E93BB7008EA14C2FC7C3461460711572C70699
+03BF49F11F3CE4556FCE122A015D54BD188BF6FDE4889DDF7A92CA1FD50E6604D11DE3B3380ECE
+1987E9A446BF220E0C93230AB2A7C6084DD955C3ECC1CDCE0187A0E564CBCF68F6133C0F261320
+8179CABDE9FC93685DBF8B845C25B7249F11EE48DD48504759C765D17D387E0CF0B20C70B57377
+AD90EEB2793FC47ECFF08645BC4F47A702EA24FD69001CE5283266B371DD80882C9886F231E2F9
+838D9E765093B77E19247365F559B075CE1AFF75671E60152047D44BD0B69B168B39582210A09D
+224F5226715581F43A9A6BA2D46968227D071CBF3EE13801CDD7F823F3141BBDB8EBEA60B48B26
+7898D5E27D431BBF528A5EF830E26E880734F6E1375ADDF92739347E128551D7E126ACC2A82FB7
+C57336E5653BF97A69027C90DC7179E65F76A7C43598F000A723A7EBB299E5B2EC549859FFED96
+28198C2C02A4FF2A58C0EAC12497B16A06F67CEE100BCF8AB48BA229F930C3D80752D05EE821A0
+C226AB62858FDBC6CF53E9B225456FD4F8ADC62B582CE583054547E14D0EC426E1B00B5A8E3421
+41C52E36C05FF715953F1BEF7AD3A36C92205198A2EE73144D89ECDE4E5B760BF5E64D09858B8A
+DEA9C12FF4BE89B345F2032B7D40F1F94832BBF21E7B6FDF42A7602688D0545E1AEF166B8F78DA
+BA20110D765981BCD22C6560B769B52A4B5B7A14A329BBF34E5395F218EDCA121500E3D698A705
+B524A3A448C2EED6E5F17FABDC7ACC3182959C7D969A5E37E9C39C1ECFE85DC9154C84301DCFC5
+8337ED83103EB593D165CF7F5339D748662AFDD55060BF1E33A0D73DCCEFAB95EBC614E23E5B0B
+F9B900E92FE25E6AD98692A39B164EA46B88368F9AB8DE07953B3A9F0D889EB2B9BD06CD6FB265
+15699BFDE76CADE3A9ADF56CCD694408A776682CABD4CFB8D3CA37FE900B46F4D153CC3C58C36A
+D79C692B71B36FF152CF92FD8898D193D3053A16067EC47FB0A5EF1BB806C5BBD5D75B613667A8
+5D1E73D8B72BA47ECD1702B524B9DDACE9ECFF9B10FB9C83E12D7C9D7220EB8C74759FB0C45F68
+92E5C6B3A502F06F45608DDEDAE2D178344D938CB36B6EE82D7321106D2C948201B3D7A95DFCC7
+BD3A1086A584718E3E62962E613E380CD99EFDA0DC033EB33E316BC8E9363B67EE5E04119EA06B
+EFAC94C4C44448812B1A7F7FCDD0824783FFCD97707304D8275AD1746A6990C3C2D5607C72F775
+4F150A3B5F6175F453EAE89CF9E3A53BADF80115B7858E113DEBD4ADC2918F3BB2454C35C3F107
+7C2D97E067C98B0205613B145F340A37FD60F7176D265BF6451256269CAA16A48D998D80581F48
+CBED667D690E855E235B4266E8F3461933D9645CC35214AF73C4FC5A42B978A54BAFC561FAEF93
+BE0316B2E4B9927C100CEA3016DC42B8EDC939AC6AD5DA1B6FC86F21D92A5B9841B21412607402
+7559CC1C3DA05536033F2A0AE7F10F8A064AA145DD79DECBE6FCEEAB4C91DB9DFAC173AD124DFF
+0BBA9097A84E8D351780382F7713E15F73C5CFD3C5BB48726C45D383FC2BE2732C8FFED42C8766
+6E0AAC7BF6AECC01E98A701526D642B90ADEFF9C48D5B70728EB378E93267E1ADFB7444BFEAF47
+25FB5CE72D8EE7DDCD03D3165CC32429D87565E7DCEC9E21FB34C1099E4AFA0D1993D4EA3B2AD6
+8D2796A5FD2CB2000DF2D8C730C7426854554D5D2D42041BE13AC3731860774B540D88806493CC
+E8188C2F8BEB189A484D9F639E3D350A6776B56C2E51A56BC96E2773BDDA339098928E095207B8
+B485BD0652F107B8E5ECAEB68B7136F12AE4630EC2D9BD452283C4F5499BDC4A20073E37CF77F8
+68A417708EA7DEA3E7915AF3D4B3F1EBDABB60E37C3CA374D96B31BA0031D53DE839CCE388FE55
+3C073C1BE5CAE06DCE8012B1A91942068BF1EC74EC261F28EC5DEE7953DFE6C4C346F5E44EC312
+7610389D265A7530E18EBA2D3BEB6D0FC64F32DD4D288DE6FCED7086A0FBFC506F736279F97F05
+2E4CEADA7AA92A5F23EE5120FD2DFC954E5C8DA037E52D63C723C55DBF0CCFDDEB20741D16F5DF
+0C2A5A0D1275BF9D3F37B6086429FEF89F59A970D44581BA0B66213F51C4CE33F104AE08A32017
+06E285C69151968DA35B2A78082E587028B405806CDF366C5D4C6E04A6F39D49C0BC23A36A4BF7
+681A3BC69E93FC3063F81F277400D2B45B931BEC7D087F31BD3B47B3F17AE6A6E4B49EC5A44234
+E55193D981033EEE43B79ABAD0752ED28F01BF12051B4511A43C2E8ED484D9D363FDE0129A311F
+A62E3D2BCA70577AF1179DEE5137D50C011F74EEEC1230651E071BA0CC9DD9D7D4FDFD21F190A4
+25E8988DD779AF006009435AABA80EA233B9A68823DAB1580742CD026EE9EE874723BE5AD6BABC
+FD9DAE0CC9A3E4567E1BAB53A5774550768EB4344062525D0836827569EF9A9BD2CE53CF85D7B9
+14C8AB0BF01A9743B86EDD1764BE91F100CDC9270C813D8B3895A55B46528B0B90CA2820034395
+8C566F25ECAB193C2C126E594A38EC6548BD47CECBF94550CC9DDA5DA4AACBA2AFD4CA53970935
+7FF3E4BA59BBCBAFAE3086F4D45C02B8592ABF94200CB8BB560645794014B384A5AB8C34478222
+BB942AFF1C95477C997B0FDEE302F01F7A52E461D10B0241737574BE4545889FB58642A3672A63
+CA19E8357396D54E18B6054BC91278159C22B391134A997007B04E98B8B036D8CBFCC457959A98
+858B734485736A5D1C932BCE464BDC7CFFA86FF1A7DABF37959D23C9E436FF6DF665E147EFFB5F
+7CC0794B01F3B87CB74020A272A798697D12B88BE43BB192BF8AB33B474AF17AA13C3CA3190C10
+F6AB16C589D121738CD71EC64A610E73A2111220C2804D3C602CBD9047DDBEAEC51296203F4DDD
+130D6748C819305196501904A00E0A52DC656A463DA07805852235ADD5BCD6953F07C700000DF1
+FFB52C5EBE6373747117DF5587D35BE15B4854054B0CB08AB96D07FA4355E038ED868841A3B4A1
+FA58FCA715CBD29D4D34FF42DAFB7F65A3990B974AF26D1BE701AE5E696EABDC7A997C4288C4C8
+CF6C10028C49E763DA39F26AA17F7BE65AA155D49B7594D702AEEDDA87891CD3D32D198F0CB233
+5369EBCB171287550EBC0394DBBAE9A637A789D052C7C51BC9FF6ED08791005BC6C0D730A49016
+AEDDD6563730AB510EC2BFBB8890D289DFF714DD074848DB372B453844EAB8396536AA5B93B6C2
+9516218F50622EA5B44B15066AC27026C40224FAE3C0A0A7B26E7271251E2CE70EFDA448B83665
+29B147BE0C81E4FA0A67D40D440CD80A0D5649D4EA919FDB09D20E4FD7AF7A8BE4168045097931
+7EDD65B6F16012995935C27F7318CAFE60494B2DE7B81D6B3813CD0075B5C93A3E4C907F277347
+32B553689DD7E1BD92033FECD1425DEE94E68DDB2983555FABBEFC10B3EE02D5836DB9632FA5E0
+6E3D18335BD999F4F2AF2222997392B905A262E87D379F3828E4225082DBD1F805FACFF2B6EB2D
+A85C06DC8BC7A1B6D7FB7E33F30E57E75133246946D05A16A6D5F2BB73F46B1AAC466005BC64A7
+0C4ED52EE20E31DC101B1053FAB7D4D8CD2159CB260421B3261D18AAF221A0E17DF1B84035F573
+83D3FBBB1509D7744BEDDC79A21FC6E4E2CCF6EE21F7C1AA792823C4813A812A903402D36EC76A
+B3840BB45D31277811B0CAFE17A7909B39B8B139A6AF831D928F751539625CF88E56353E2559B1
+E8BF899677561617726941B20A123D6EE3C6EA8F5FDFCE7EDB24C47FDF560127E219C7B70E359A
+2F8BF5ED5696C589BC3DC55B8067609C69022CEAACA887F4D42F5ACDCB1B7A20730739D9F64A35
+9D76372939492FD3054DCD0543D608401A557058DA16E13041135E9E7A6A0DACCF3E4050E01E4A
+F27531777C2EFA12F82281B7CED3A3B49FDBD0FD218CFB3407858EA0CB5401769E5583CAA61ABE
+0351F66424144EC51F4C969C160FF37477F887139BFDFEE290FE77F0BE527103A6A30DE6C3494D
+269386B8525B30CBEDF4D6C2BA04B5C843F76B07A11935954F48C55B9BA63F2B1DC3231B5FF9F8
+75D2DD2A071B63DFA057CF9988A8646035F625F63E892C449CE2A90A2324FC7474B53ADF072F5F
+6B389DE6D4243B13DEA6D5DEEBC9EA428FD35B13B3648B8084AD3034C40E683FA6AB99B322DC91
+A946911A63B70B0B0A604ECE8F5E74DDE98261781218DF73B6666ED2C2E5F4E317BB6CEB2555CD
+82A6A1DCCA0564AE1C7111BBEFA789880448DF720129F80F856439F261172671801EE0A690C2AD
+B81434FF0A56F008A6B35CE08C8832EC2393DC62578CBA2EA45C07E61FDB658B31E80EF9EEF1F7
+1C776ABD17A17EDCF9E852386C0698A55F384F4342547CB07C038CC38426457C67C1E8FEE0D424
+33B7FB9E68DD533550F1E321E0221BB47658C784E1F2D81E40205F919590B71658F02DAA29CE3E
+DD19A2AE8191CAB3430F61D4899DC44E7B8883A3E6384B63180F500891BF54C75A7E0B679C6CFE
+9C71DCB785404DE3279F228B9389953BE4330497B00D90E0D164433FD693B3AFDD4639A669CDBF
+F930558CD2A9C54031FF23EAC02FA2FC878FD29894FC2A3C181BE30D7C80FD5026B0E933B1875A
+EC4A1C3B09F0AB78B686FDBC60C7CE7998EC2A610DD543C70D1E7000F3C4BA6EF15C0A0CD618FD
+08A0646D582003E1BB8C4C28CDB11FFB0B764023F023C1BB8486BDBC341D865E04839820CEE2B8
+F0FE22513A8AD2DFACDE078504648010888BAB29011996575E1869D1F8CA4784B8488511080E98
+3EDA926D56FF4ECA3BC6A6B16B0D0C720A62F363CE48E83AB5FD243121F08AD6B47E326BDBD5D5
+FFC684307F3C40BADACDCC8049118E49EFAF4F9570823A9EDBF3FE8121C94CCEEB2600347CBCDB
+C08FBCA3A972B4411F7A5EA4E8F1D890779AC095FAF29103242B8C090F645AD8CBABB555D50B29
+69019113712C6F058408F1080BC71302C2B9B79647FCB1CF9DBD9ABA4C5D6AD2FFB010E8C734BE
+14E618AD1B735B099F0FB59B084C11CCD5579071E8655430474F7306CA9F49C46DC0BB548E5A8F
+0D608E85881BD83A1EB98B4E92FE12B39E9C7ED86C46627B6CD527C4D3D92894835F47A80F1F4D
+B0C73387E31A429002C4045AE770576E543B63B2A1EE2DD7F4EF11A1223E9514C9D75141101170
+F2774E52201AD076FF942ED6C97FB6D1D15E7D7C8391C3D25A0A08422202F93B33F38E58F8AC97
+5A41B2549E95C5268D79208143E420DDD94B97EF2ADF9E7C77A2F38BA50E03B6BF43972FC9B19C
+22D071CD79F26BC6A2AE9442E57A3E0DC49F30B1A3F9A30D8985900DEB6CA9090B90656EE40CD4
+4F483415C71D4BF140E3D9A1617CE38320955680F74E120F40503C712E4438EED9354969E3217C
+2F297BD277D1B0C120A8DA45E2BCD0DDBCE00EE2A5553AB493918AD82EAA20AA736DC5B93BD0E8
+094BEAFE5E3181D39028C1A2E30CD6B2816150A81BC3DC69C9A3B732600C45FCC2F0B485FC9B69
+23338458A054C570AB6F8E3B284E07F223B843BF38122A2E816A458D6A062E2E0E1B76060082D2
+DF3B4A5FF911C089698FBDA697CF2A3FA47C17A734FDBB33EE87A5AA068D21745CC4661C19AA1A
+E05A8C6030739EB01685E839793CD5BD566353436380622A0D597517B684C04965DC1F13B5C611
+6C549DBDB42AFA964789A223EDEFD10C57EE4B1BB1B06B6942B64EE66E1D67E82D4CEADFE47ACC
+35080AFE3657BBE687E353F4C94A3788A260436FA1C114B9003DF5DA81A3A471624D73472D61E9
+A616FDAB3ABABC225C845FD8F12103B8F67474D7414833074E47222BC00E86ABEB6D8630DF3A9D
+84E981EFD99C9FAB64494894F6BF88045FFCE054C50945B75D2A00BBFF2F68EEEA5FA19D5F863E
+128CF160182CA8B38EB1560F07F4DDB97E0E759077E70BC4C2B309020840C288951B56803394D1
+D57B46DF96DDC9777224BCE81E9797549F18CCC16CA7C25202C4569EECCA6E48EC9C0D911C7D9D
+A2FD831635D913E54A181E56F8808E9A8D27BCA1C4DF10CC927794F64018A4B14E003B885F0C18
+DE9DB23401ED18890021623ACF1AB9C9DE1FDD33D4F6903E4CA4C668534F99F05CDE08647B3FA1
+A8DE467C565D9BA0F6E1D09595B886353C8C67E5095BE53F1A841E258BF2B8FBCDBA798CE77B7D
+20D39940E6F6C8DD9A004778BFDB57BCB735DB413236F0A7B864CB6CC3BBFB1B33A23EDC484920
+E5582F8248933D9EEEFC1E5E5386567B576D0362FD750EA3FC631B31E61EE1C5D3D6A0AF9F4E8A
+436212D359F7BBC9C69DCF4169EE4A5DB65A990AE63E4773607DE4A7DBB85CDDDEE4FA65018C23
+0900CB9F868885CF80AE58907134616D78B7179130F76557557BEA8F19B62EF87F9F8AA93A5F0B
+DD78C6CEB352ED458806DCE1DF7DF2E2CC34B724C61364D707EFC4EAD4A8E3DB732E8FD1B5DFCF
+8C3C46D531D266113B63B7D01FA053EC28347FD23A35CF986F5C73378C8ABD12D1A02B98EA98B4
+0F4ADD4F4226D773BE1ADC9841082A9C9E7A5F99534FD6846127054B2437D220A04BF83D16EEFA
+7BDB4799DFDBD2DADB1276FFC40C6C24F2253245F21E230C822E323CAC694FC0B7903574CE5175
+94F6C22557E231C26768C5DA5572F3D473712C85225BFBDA924766D9544ADFC177ACF94798AB07
+985FBBB8A9F230702F3302B1511665B81E33EC69A61F6EE5AF160A034784C83D0BC0039E04AF3D
+C8EBDE4DC0EEED8F1FA37D462EE55E63A3526E8278AF663BF5BA1902CA695E8AA7C4EE020FCA14
+BA93AB5A0DEFF681E7602135A13DE7567192764DD5D26B1B5862238FF3ACF20711FE0C24DA756A
+E629E477DDABF428FE4E10AF898CBB8606BAF96D29627E68A78A483D47DB135DE7FC53ECD46A12
+9D64D17C3FB16BC53CEF1F1581976BEE603964EC3CFB28EC4DCABD6DAFE9FC854C69341DBCD4AA
+1CBEB29789AAAE56A5C411437ACE39B035C26F77ABAAB2524B7EA71BB664815BBA7F1BD857BC69
+281071E74CDDB91C28E59C3007EB2280BEE16E14110AE00324B0A72C65547E3A0509B769608FF7
+4073E2BE295BB71ADAFF01E81EC86561C7095A2E5840F54C3030A83045593C43216B8B53269CF3
+BFA5A16BC7F258B34F46B5B505BCA9B5349F181D9DAB84372994660A77742AEC03AB32A3A95253
+7782C7F489219B19393A0C1A5D9EEAEE305A1BED8376E534163B3303AE930E816F818AC3C5314A
+5E23460D8E6B08DEEF8FCCEB7F89E83A8805708CF5A6B2961455693109059C09182B7E08AA1C32
+61863F6F546CBAB64E249BA5ECD7AC030973CA1C69E3A37FD5474594181F53528300070F404F5D
+4C2B9D43AD4445A7CA703F67B46B2735F7EC1D01B3A2D023B11AED0891AC2BDE28F32ED40DA342
+0B6F94EE07E269F4A8D07E29F13DCA62E59E14F3C84FB1836073DD34E29BAE513F9888BBBAE7FD
+0F0EE251534E4D7FA6F27C64992A134E8ED6910B29FCE7AA2DA8A58113422E4798DEEEAA323035
+170A1D20F6A4BD68C5F495F42648210BB8F056F5DE8420240651AEB4B03A43D18589E2F8CA7380
+3864002F2709D60BC735C6CD5692DAA22D8BAD66144ECA52DB3F0910680EF1376CDD3886A37579
+A1AC30E349F9EC89AC8F5D7BB880D459BDD538FD516E9780B09A907E1C047F2D5EA6D385CA7B11
+32BB7FF7E81539D4D7EBD5C59C32DC82B44BC5DD698048789CD16C51B072F73E5A6E68546BDC32
+306E7D197E6D4288D715C1902E58B6E93CA321D45F7E82E379D569D040BC64352060E138CA4494
+61CF8E51BEA1CC4A9ADB6B5C26A72E6EE8C089E5198615A621323FC9620FA12770C36A22AF2277
+823090F7D058D3434A894FFCCCE04022686AB11670DBB6E68FB6E2336D6C18569675D219E7B6F9
+FCD6866FF8AD749B6CDC7EBFB573757AF230A1E9BA4F2F53E8F0F20660E105F5733B3553DC17B0
+580317BF4B87376B53D6C668F169723EEDDDD1776DE62B7E0E0E966C5F2F43DAE61339596C436C
+64A2369EDED778D98A65B3222148921E381BB46FC0BA1DC3DDCAC224D0B9F0816C00BE91C50376
+9D969FE0BA42B89452E84B4F794B7D9688B66030C7734F63FCBDAE262E6B4FFC1AC235BA67E0E5
+1331118FC59B325B630E6E22CB55321928B7D153759A11A47DF9D679CB9D10714C5FBDADDFA765
+60CBE22A4D25943AA856B0B0E190FF911980914072C697C556A91B894D3B1A096E0AE9A74D2610
+5CDD88630F89A00EE9BD92BDE8B806A2D1D4AF265C796D1EE519D25CF196BFAE5CD837A0BD2F76
+A76B4EE2241B2CF9D89810807AC10B3BBE67179F216FC44920E28F1FEBD64C2750E1FDAABDF1AC
+1DEC065CD4AC4239B3DD6A93CAEBC22BB7097FBB4122ED104DF6A7D1F4C76A1C8132FF188B2438
+67B38708F8CF59563E72D5F82B302F2B0FA4EF4D877138C14E250D36032E9D53B48F6906D73DF3
+A682439B8AFC64FBFA324C56D825315C8F3FEC5FB3D8F73F6292D617D29F427FE5DFC85C3F2DB0
+882BEBBBB704102B3A53918441A507F6F468E4EA1B8C46A4E2DFFC654107FAF494C035C0A03359
+1B83E8BF142162C7530A1BE5618206B97EC7E92B1B80EAB0061746AB3717ED65EC0ED719F2A1C7
+3F105D88687FC5B00617CC7CD288CE7A938C9F9C4522B7B43ECCF67EC5F342B62085938BA3C1D6
+0255A9DFFAF237D6CF752A52B252BB6C5AE4D6EC39F7DA8427D6BC715D7ADA63743E813AFCFFE0
+A07F8229FE2074A82E315EB7DA0448BBFD41D06C4CBDAB1DC014A259CCE764AE969B1C6322A1BF
+CB703816FABA522713B50878897A91870943B20869D52A01DD76695BFC30C39595409EB8F2FD69
+97D7A3820E2DA1BB4F7555EAB7422CC31783E2A20F54D9B8759CE29F0461DD43885545FAB24357
+C1013C1FF6D778A01853AD30356382830F7653BAF57E2F6C3AD79CDDB2BD9376EB94616F975D83
+D85214593FF76FEB63297FA6F9A2566A1CE29811D81A03FF5C5493686DE4C5AFAB19283ED36241
+BBD6BAF5573CB6EBBF8DF5EDCAD5F69E8B65580AD4D6A4FF6C02D73BD52D21B73A6E69D4857E99
+BBD2AE2714A953DEA568878E338166311B45CD51A8FE1E0B6E6CF1A03193F82A8E428D9C3D2BB5
+1D26E0AF099F2464E235DCA9899BB75FD54C37AC15098E1AC9F33E49FB89E0F106FE9BE1F152E4
+E33DC4050C3517B5EF7BA154F0B267A7C35115F6EB6BFA3D061831BE470F5478A664DFC4E0AEE1
+1300B30526F50AB8274F3D56BABFB9623B0C7D7030C67EA7088E4B1C767F8A00A01EDAE880EB13
+D2E57C909556D6AF8E067AD42A1250E61D50ECCC72F67B50BEE2302AD6E670E0C940C6D3FCFD8F
+426FC6B8EC86DD4461545742E2C1952AE52EBEB78FE286B72B75A3D7C0F0FB97876A85421BC38C
+CAB03A436E42A09835569D741679103A52ECBE764C4E1B6FFC50738E98C154CA75C51925C5744E
+A5299C85331D7BA5DFBB67E8AA8DB9C4EA559C4F6404D760EC9FCFC572B691E747FB7D6BC47D9A
+43DF3F8B6873E929058A30D37087CCD0A7A7C2593E219B19B2095EE0542FC49E7B7EBC8FA6208B
+96E891014B4BE49BA7510784271E2E8B4D2E4F6520BCC4EE5C7633B79150CAB9807A1B01B50E81
+BFC2B7B190A3A848B3DFC15E8B47AFBBAD5C7497A564D927B680B0976C5DA2693C87F18356931D
+8CF9AC134A4A496FE850E6A5091956B89776BE6D893981E0279F5D01E605CCA08F6B4C32A6D01F
+1FD9E2B243EC60D5781F4B2D6FCA13CFFDAC188F4F39A155B0F64E1BAD587E8C1953723C6C59D4
+7321289D9A086DC57FC08F7F2DA512C57A3B9CE4461D711F25E495C5E50740A364798E6B5B732D
+6F17EAEA63ED222DEAF39D2E813601F3B2F416465776CE7154242C5CEB14F6CCBF23EEE181EB1F
+92DC7C580610902C6CDA5FD15E096317549184CCD14F1AE54CD5688D5FC329114DD48AF6DB7524
+414DEE65B3528674768F9DA68CA2552A770E111D3327943CEC52A7B23DC55A98CBF2C0D3A6E2EC
+F15A1F093E391AC11CAA0922696275B87137473FF0EA59A1ADAD12C529D76568DF36713DC914D5
+7DD5E298A6034F6D918DB3BEDAF88E74907F4B03C41B5ECB0773FEF89237C9C611F0DB6F3BF1A3
+1EB60AF8343680184FBBC3136257D2777802039F57F2BCA2B1515742C64026848B669F8D0DF5A6
+871858230EA9A9DBA628CD40269F33D9B8AF5DBA58D4BCA52F8A7A2A38E817B7039D6C4B40DA09
+B4F2DAF8CC12E14D96BFF75D61B4166121E56DC3D0B2D89E31BABC8E1308A86D0F6E3F28B4E873
+28CC47BBFA115500E22416BC153A68AC0299BD50C833E3C1AEE97EEF711449DCB33B20763E2E65
+1D429B9D3EBC3429E942429A00641715E268F9E226C0FCDA7A2193C42FDBC3F6A6E668F27DA5AF
+D2539C04D7CE3DC030880DB21B7958F625ABC5E6DC94FAF9B8469790DBFDE65C89955F83CA117F
+8E43D8AB9E5D8664F08A7CBBDAF4C86D786F4F0FF19D9947D08317BB5E184346EA5A164D9A558C
+EE77581AA92DAC056584ED36663EB708D1114D73A00A001D440C8C338E7CC7710DFFAC6E93696C
+FD245663F457C5BC29B9029BF91566E8B147016F0B3104BD8863F104A6F0E431CD33BEC307FDA8
+17BC5571D98C3DD1AC57A899787F2903D410941CFC818BB56C19DDEDC91295ACAC20931525182C
+091AF85AC3E161FEA22F8E65B44E746F8FD40754226439FD9A660E2D02E1AEC9D9BC214F5F16A4
+D5BA4E1364D8E8C80A8E57096B510B5A8FBA5FE6715046BFC52EAC796F23B4CF996F8CA9ECD236
+1AF5D627A4076F02BBF615556801BC06D014A020C7A4D7BF87CDAB9EECFB90B4C8F6438E28EF59
+9C08E1646D023449FE2563F481B23C5765CE24ECBFC6EDFD5E69294E7910313DA056CD9C75DCD4
+722371BCF97AC6DD6D2DF99B35BC98C05932BAD200E1F5CE5F1A39BF2F14AE9BCE79157ACBDF8A
+E4193C18FBA2271AAE398BB618DACE59C98424D17B4A9F152912B5AC21345C1E0C94631CAF2B51
+1DCAB35876A204F0BDE78BDB5F82148131DAD9C0BA3D98EA870BDFD86DFB920006DBA5B4037B83
+1255A44112C3C04BA51E3EE35B72E271640F37E6D1929615D75B8574BA58A2CF22264E1EBE3AE4
+74C0CC9EF06F251D9A702469CC838F7DA8EE2FFC1EB92368E839D658DA04AD3FD83325A439043E
+6489945004F7383B5B77F9D799F3CB07D8E4446A00A8C1DE81D01F48AE998A898785609A498CE2
+FB0526FA2485F06F4F17E54141455D0C6E1D8D337BCE938A70FA1F9EA9B2C1FBF1166E26A0512D
+E4C347254DF67369F91B82A1743F1F26794DC06C7DABA10079FAD6FD2B559DACC704EAFC12C204
+CB0A6BF8C97971D1094F307953947B309DA4823059A83AFA23ECDA8FCA4870E5949DE858F036E5
+0D3F193A705537E7A131256E72FC4F4949C49FB40C470480464629F987D6E4058A70D28ED1FAF4
+82C3E8E402BA5D2E9A8ED50177C356160F2D38A5D18775E2F204D9767953F3FA4C0A0F05EAFA33
+AA5788CEC8E64948D6DEFEC409901F7C2611110827B401F3A7A309DE2311FE4A27BC9ADEFD3B29
+7E86C696C57C2C70066438FA37876F8C0275458F82E6FC15D6B55DE4CBB8646452A26FC3D8248B
+CADE704766582D20946FB5EAC8739837DCFF5A1E84EEA8D9C21D137CB93DB74925250A0336839D
+32C115A5FEF9ED71D4E5A505230F6AC17AD3773A5E5A094BB3900FA0BF3055897966A0BD052AD2
+1E5CB6F327300D77CCD2A0283B5868023E86E50E064E850E45DFB3278799854C055CF83FE98AEF
+8A5ED9059EA6C1EA5B4916F4673782335EAC2836507A3A2AB61917E24140454924863F30E5C7ED
+786B5379227D4BF411FF8FFDD037FC30522BC8CBB887E860D871F59628E1FFA0BFD7FF2DC25700
+8E5DF7FDE2F02DCA442646EE35238075CAFB8ED068E50EB4D6B82EA5F7EB3DEC3C9132A8ED6F15
+59F530A04A4550E83A87A09CE39F699CE8B42D17EBC0EBAA6B916CD36C766160357404B227FC43
+1E1AA8E34B68864C18BE49995C92581AAA084D6FC95599770D84E567C3A45745D84A9DDCC9ED17
+9582B3F4BD021A28E9913D8BC40FF6178C7D0233BB2D876F91B3DB7F9B74A6EEDB70D2C363E8BA
+D3D69B1C028752D95086EDC8CFCDB2DAD247ECDF88A28F245BCE710B796C554914CE83E4D967AF
+C305D6BC70A004ADCAF4D354BDA1427DD0CCFFDCA32D9E5E8EAA67A37E145252D468ECED627F20
+38BB4533B00475AE81BAD8A49B9C8031E3AFE5AAE493E4864D5B9AFEF5331E4AA436BD6B6FAFE4
+3073C9DEDA76821B787C8C4CDD42F14DC97383648AFAC72F50E40671ABEC730DC100D4E442B762
+42726C8E569AACF6E43ECF9E5376F0BF839E7EE78689EA1DFFF44E97F93D0A98D19520DAE6F4D8
+8A6159B19FD2897878C26B816FA99DF3C99A5DD18A702A0E285B0256326636259700ADB9D79608
+F0341F6753120DCD82D4D80DB3F3AFC0A84BECE5C6AD87F7E0BF915ABE08E7F39D92A58894AE7C
+3753A68CAEB56529E899D29EFCA137553DE0CEC1E27FE7D09198237B25B33EE059424E032BFAB5
+E8AE55336A9A22BD84B267B8141EEA7A0660C75C32CC9040C91694DE84E975BC52797CC4983A44
+044E9EC79183C985AA9994A8547A9AD5FD9BA515A79671B7E912974B4BFB58F3C1F4218987DEF2
+5753839C5A335C4EF125596A19DE6D28C10D648FFABE683D55957737AAF73E85593F5173E70A8F
+9136943175FC0A1CBA166FAD4857AB9405F3CB1C96A824EE045D579436967ED9295FDD3C7D931D
+9A77539F886F768FAB2D8EF6A987BC0452AE7DFC2BFB25620EC056246B7DDCD11E68BB3A2D055D
+F0714AAEC08E88067B6C4DB719E49F1C310BC367B67AAC68CB72588D9A11E22DDD65215EEDB812
+78813D9C09A97E219CB5E968A8882C79EC2BF4A0B55761384D585A7E48981FE624117FA09AC46D
+5B6E538609292D9C63874A192C1CD25FD5EB5BF30E1602213CCC5708AA7A28775AB1D669EED45B
+8AD5BB8AE72CF4C827F34228BE33A0CD40DD3C1FA757DE434485E36D09800F1C2D28323B4E7E73
+C8F5F79346D87C617C5BFBF6E908322FAA26ED50BC66CBF71E0C026705E162A370822AEF8AA022
+860164E7FD1E7FB81C5E14DB0A81659DA7BCFA650B72112994922D416E98D30E3169F696E843B7
+B34C554DBCF8029FF5910539A66F55B7666B861BD7E2BE7A9B00D44CE2EAF55A98AAD03319380A
+8F8378EBAD79823A27057276F9FE454C119C03E20241674F5896B67AD005130498711BCC8CADD0
+265157093D22A1F7CBDBF2A3381AE5A4BC07F316872418AB2F6588BA21DB31D7B0CC304CC2E23D
+0F810DBC488F91954F5F28A82D3D53782F399113460B0DFDEF872FA825C94262A70B1FE72933BF
+40FD4BECB14BC70B3F43911BC04948231139FC4D86B2F0854F782AE4B9CE7AC33EF50275AFB769
+C73435800D212094117D0DA5B694819DDA8600BBB6A098091C888E32CE9F8B3BC4E67757719B13
+420F989143F2E0B85B2DA6A695AA91DCB5B69186A59CC232F2F434F2D3FC1657DE90D3698230FB
+D39C19B3B62F18ED9258D1D7CC8CBD1CBF58592BDBCCDD164C8A483AB70127F4C9E660BBC673C6
+3EED28CE5822C2BF20A785C0D2AEABA3F4061A585F5F48270A36F11B6C5077310BD00FA21475A4
+E2E60D99C8A1DD5D74B74CA470D964157C7D4D4992566D36558E58B7E07D091D7F9AA07CABF586
+F248D120917AADEFCFA4F689636185D53AE061401AEF4A3A19F8E0D9CB30B54979525D47AC3ACD
+E79FE768CBB1AE7B0A2BF509D102CF924D0D859F89CD39BB99E2883C30A4E148D1918F1EDEA095
+149B37774ADCB4B3FD6C0345EA23F0213DB4F29A8F167324C2A1E8CD9BEE21AE8CA621BAF73145
+1AA582E9FD1EB460899A8C38B08ED183929A81ED396448BDF527F409644D17B4A005B9862F5F7F
+B95F2155BB93063FDB7E545886477B5B710CD2BAE103A9CE1DEAD4F15F63F41C892CA84C62680D
+D511324931D4E51831C25CB2C119DEF8E5D75A9A585B0E4C89FBF74B21A1A8E2206E6EBECB7304
+CB1DAFB7D0C4000DCE1A244A29525B3872B14F29CA1C9BC17CCE10B135E0C3F530F77AC7AA7C0B
+059D07AD74EA9A7C55E9FA75B381CA902F13846C90A2F7C48383D1BEFC94BBD0103B991B79C1F4
+DB3EA8B83CAAE65FFF6B077ED2471AA551BAC92FFBD6100210C1CEB57225697BFDCC5C414B8EC7
+59A4C3AFE8034A9EEDA112D991D078CE7522CF3990462CA35F03CC7509BA2E30F7B5BE75F0352D
+6F96D914A53F9AF8975DCBF3688201102A3162F68E4EA8E249B94D0781011FD9E0CEFF944455DB
+2F6517FF96E2958EA69B86D96F267251044AE073089373B7822513E0FB589769391BCF2DB62ACA
+DF995F020A2BAB02E0C972BC4A7F6B5F7410CAA369022F2D1B5F861C5C5276FCF4EFC65449DCBE
+10E069725ADFA61DB972476EC495B544A174ADB5177C080C5EAE6B44E6E044DF660C748A935F0E
+7AD665C390C73CB698B1FD187F9085F58AA14BFEBDA9BB1730B2BA5907CE8C790438D4EB02280B
+B2B611BEEF36F75B636177E6096C0E1E31F8240B38318DEA7626688B8A0CA5817D8F281AA804EF
+2B41A8CD7605F02D032498D51FE3368A00336084D38B29372931C2CCF738731F9EC569E3B2D54B
+24411425B6D39C891393D00FAD30A4939848B4B1D5BB9FF68B345D5901CFC4DF9DEFE9B522C000
+086469D59A6BF467840C9EB5C491FE50ADFC769535E452878A8CF06968FA0E8B9DD30F35BBE61B
+4C548344379489E5DC966E09588FE4F269DF0409713211C7299327BB0294D45FBA35EC304B7B07
+F5A67D46A786C8247807067086142816F3ACF77F03D5EE6FF5F8A2B8369C0F1CC922B59FA31564
+3271CFD550D6927E21CCE4E8FB93F7A920339D721CB2EF9F4848AE3D96F85BCEA64B4AE93F5254
+D9D4B18991CD8C5BD76871B9EBC855663EF043A8230B344539D2EC6906F58372B1DDAC014C189F
+E9E3F73E25790CF11DB0ACB93A64D3ED9A57E11826825926629F23F332CDEF103DB74634DDBB3E
+444BF96DBE0898E440587D86F5EE18C01CA829E5D1E30D1A06F1E42CCDE92ED96A1B5AD7362F36
+F0A3E12A98CC4A9E450AB2909475814D5CD4E06C6EC137D49B31716BD1CF579B668C189A49E9A0
+CD2DD4224388F1457FD508DF001BF9F1F7DBF9251589282F55EFEC08995A305605AFDB7A611212
+B8602A817B2B5A632888886921BC94BBF3BFB1C25A518741C8477C3E445485BE65BB0C90CEC0F4
+148734EBCE7E096314163C57F1F72E083253BCF06B45580086BBD0F3A3C6626708CA8E11D9C4E5
+28B6FF99B7C5FB64060C4B7C2AE76AE9C98E5A5071688AC1010FB0A81669E63745A26E027D6A21
+505594325EDECABEAB4CE8C6DCB221AC9789676F23B2B05EDDDD215539604BF3F82880F505D282
+F824C853442E8E39FB9C71BC55E793118BA5BC398F476930AAA980CCF7DC12D24B41D2E7589381
+8405E76FA5AE74586DD032C5C8540223BD218D5622DC8A6B0587D133D0FE9F31A636C07913C27F
+20BE650D79B35F1616A6846B573B0D4B6BD560B50028C02390BB52ED835984B8F6630BB7C1967F
+DFD2DC734068516352AF4B0F207E0143B24B22530EA7F058FA80487D7C1DAA8E6E049CE8F5E0BE
+E2BD29DB095A48DD4242EF9B7388FC24EF655A2184965166E569C4D0F1DEDDD3B6B14D1E92D400
+8F8911D54E60822F4679AEA8F739E22BB7B03A5B04ECBD75A95DF15AD365068B7883264C139C4B
+4BB9D7D65CB95D2D69008696443D3EA461E1543ACBDC42BF7CB9E3AE13D5EAA317F90414A3BB1B
+94AF1A419845A8DD13E392F4359B4D145DE20BDC83B9559FE0A9FFAFFD71079A6F7FCE6F825085
+CC3577AE98BBDDDF39BB10C19541B2D65F230CC807B71D7EE35C35250775F8FC255FFF201D681E
+CF7184D3551DAF6632374E2C0066B90B3F2FBA38DEBEC7E1AAFB9E75C25E1690EF1FB008BE0827
+38C42606443B9072A0C2EF27BCDCC51CC63B751D40EB50C8138680C07F213AE287E902E8E86DCD
+FF44CDEA064F4F6DFE1E619165EF8CF42922A25A4716A110B92A83B4D2C439485893541FDAD9E5
+638BF0578FA0497F5E7D3C666B1183B830AC1925C267C1B4FFC87469A522BBC2E07D8270FEF5BD
+A7C02846F5DF4216083CB0D110809A8BD08E3BD01F3E19C096D692E481ED952D8AF6870C1FBEAB
+011BF3604A950871ABB2B3489EC07CB79102C15CFAAFAEB098D0B34040CC4D3FFC34CDAB240A40
+C26AA74C22C90B58B90AEDF1A4291C84B5E3AB0EF1D41EF30AF5E760518786C347B4AF86FBB861
+EF38C8ECAC757E2495F358E9B71C8BFC4A5F0604CADB5689F17993523FFFA64B39E9685AC9D503
+9224FCDB0EDEC24655E97530C827A587D375C9A40685CCFB532F9BC01F27B26553D8656DC07B53
+6AF6690434FF8F5BFEAE26460BEF05D4CC0358102FCE94223C048C96E004CC086D440D88799A47
+72C20DF93B83052131CD455A5498716EC46119EAD40F30FC1AE46019531490B4EB0919D54BDE0A
+1D65304A9D9DDC4684E2E0AE546F9E54AA498403FD978D029CFA934D5D4C021C97C995A43179E9
+60255181BCA8860670A701939C0B2EFF33788ED38760D6DE2B19161AC68EACC2E9EE06E8147F16
+9E17F3849F9A8459439E4CE00D9FFBA40B01D0C92C5C5CC805BB825D9D03C4E8A299AAC9122E04
+0A234B4F973E00A1B2524E0278A04EA00D5F7AB15347B967DC5A8226E57577761ED08EC081DDD9
+E1BA28FE92A9520A9E86C14B7C40C9DD49EE603EBDA359F2C39F1E399949353FBA12E1EA1A0316
+E56D615C4F6C5A481D161EA6E225994FF7419E4408C7A0778CED1FB84090BF6F774E26E2264BD8
+E55CDFC33D0F970A992F683F0272ABE717F98F46AB271E68117E6339BC0AECB9E45F230FF57742
+D4CA51C9D0E3EF7CC82A7FD880C3EB4A24BADDA4EA12C1B7DD77E002EF91AEF22038DC0EFEAE71
+D7B86B32ABC84A6983C613EC3A5C40F180FD5E68F1CE8E6AAC0E880B35DB366408237ADE529FE2
+C497CA863B61955815B9E4438087605B952CC6B2AC37F2DA0FF60B8C208DCC873ABED2E02B65D1
+F107102BD0D8459A5AE4B23950A0796B610B3EA310B25709922C0537C88CB2F4770224A3A17F35
+F48BA498AAB10F423B9958EB9025D5F041F31A312B32A264B07067B8D27EB167056E9CA67462B3
+31AF4B55ECFE51D794493A508C09BC244B700380C01AFEC1F340149AE6544437EEE9C1222861AA
+17B647D700CD75D95A51827226B1FA55D0BD6A780F31828580EB192E2E9072AD88E9A4D9C50752
+11583ED95AA662D563744CC8831F92D72A72EC2CB7FC7CFB76C89119810345026F15B4E5B9FE0B
+09C83EA32147D38FB50D003E8897CE50A77AAB784700F3892A399EDC3CB5F5A95ABE85617C2983
+DBA02690B3789BCEAC789247547C3A39BE33AE871FF808D70B3D6D12BD51E1030A23C8356BBC76
+C901868694896882C90E40C1C1940BEAFF8BFEAEC1D426A1C44B6308EF4ADAF38D88766D6FE1DE
+A163B9203E33E2807AB582AC0763BFB7E730CEE12F374108C84DF65966DCF77953C2793552E7EC
+526C553B2B66348888BE30DF7DCAA1F4EB4BFC852C231358ABC89A3630D794D7B7B5581041050D
+093998A61446FC8651C83C36986197AEA67C8F85EFCBA6A2E90249F15974598D11461012B2044B
+0C730E6525C37D1196214394EC7A6D2A92F00F9DBCF62FDB8C1D41E70C1C655A4A25D30BD009A3
+FCAAE8DE1574E5359936E6680A3081D2C1648D1A5853D8EEB72E63DDE6885578D8DFBF7E90C5EE
+A7D6F9F6CCED6C22C72177D58B8E05BCE2AB63D353D1C7DDB9AEC88E5E709CD645EC956CD1AF54
+34007DA54B7B0590AB5013E50758AA9D3AA1486DF2B7A368070DAE49C9C83C5FF98F33012DA73C
+E02827F8209AE8182282EE67E936BF65B137D85F9458DF930E668FCC2CE7B1BC157223372A425A
+E92B16556CEC07891AF58192EBF36340CA66D275D26AB19F5EB2A5031040D9A2472A0D1547FE42
+C302E23127C9BF7080B718192A4611888E1431B79C19BD95E8A0D1134E115D60F5CED1064D2B19
+59C21A9645673653752B0CFBEB9097F7747E6D45AF059338649875C5167BC91600250A8067F8AA
+9652FA4CA4F08A42B95C6279A6A5BAF6320C3FF1AB33C6D7BEDB602AA4C81E4D53C2662D9A220A
+CED6982B2F6F4D14C552248185D61D07E2A585CB87A93E38870F1C1F4D007A994126B4B6D37110
+5122A8C99FCDF07E4E05938EF82644DFEC40525F01BB06B958F787B3F94B4467EDC4F0515C9D69
+896A442EF69E9123012121EEE3B9CB2CA3F1AD1D07AA0E45
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+
+%%EndFont
+%%BeginFont: RMTMI
+%!PS-AdobeFont-1.1: RMTMI 1.1
+%%CreationDate: 1993 May 10 16:52:31
+
+% Copyright (c) 1992, 1993 The TeXplorators Corporation
+% Hinting Copyright (c) 1992, 1993 Y&Y, Inc.
+
+11 dict begin
+/FontInfo 9 dict dup begin
+/version (1.1) readonly def
+/Notice (Copyright (C) 1992, 1993 The TeXplorators Corporation) readonly def
+/FullName (RMTMI) readonly def
+/FamilyName (MathTime) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -14.036 def
+/isFixedPitch false def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/FontName /RMTMI def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 161 /Gamma put
+dup 162 /Delta put
+dup 163 /Theta put
+dup 164 /Lambda put
+dup 165 /Xi put
+dup 166 /Pi put
+dup 167 /Sigma put
+dup 168 /Upsilon put
+dup 169 /Phi put
+dup 170 /Psi put
+dup 173 /Omega put
+dup 174 /alpha put
+dup 175 /beta put
+dup 176 /gamma put
+dup 177 /delta put
+dup 178 /epsilon1 put
+dup 179 /zeta put
+dup 180 /eta put
+dup 181 /theta put
+dup 182 /iota put
+dup 183 /kappa put
+dup 184 /lambda put
+dup 185 /mu put
+dup 186 /nu put
+dup 187 /xi put
+dup 188 /pi put
+dup 189 /rho put
+dup 190 /sigma put
+dup 191 /tau put
+dup 192 /upsilon put
+dup 193 /phi put
+dup 194 /chi put
+dup 195 /psi put
+dup 196 /Omega1 put
+dup 0 /Gamma put
+dup 1 /Delta put
+dup 2 /Theta put
+dup 3 /Lambda put
+dup 4 /Xi put
+dup 5 /Pi put
+dup 6 /Sigma put
+dup 7 /Upsilon put
+dup 8 /Phi put
+dup 9 /Psi put
+dup 10 /Omega put
+dup 11 /alpha put
+dup 12 /beta put
+dup 13 /gamma put
+dup 14 /delta put
+dup 15 /epsilon1 put
+dup 16 /zeta put
+dup 17 /eta put
+dup 18 /theta put
+dup 19 /iota put
+dup 20 /kappa put
+dup 21 /lambda put
+dup 22 /mu put
+dup 23 /nu put
+dup 24 /xi put
+dup 25 /pi put
+dup 26 /rho put
+dup 27 /sigma put
+dup 28 /tau put
+dup 29 /upsilon put
+dup 30 /phi put
+dup 31 /chi put
+dup 32 /psi put
+dup 33 /omega put
+dup 34 /epsilon put
+dup 35 /theta1 put
+dup 36 /pi1 put
+dup 37 /rho1 put
+dup 38 /sigma1 put
+dup 39 /phi1 put
+dup 40 /arrowlefttophalf put
+dup 41 /arrowleftbothalf put
+dup 42 /arrowrighttophalf put
+dup 43 /arrowrightbothalf put
+dup 44 /arrowhookleft put
+dup 45 /arrowhookright put
+dup 46 /parenleft put
+dup 47 /parenright put
+dup 48 /Gamma1 put
+dup 49 /Delta1 put
+dup 50 /Theta1 put
+dup 51 /Lambda1 put
+dup 52 /Xi1 put
+dup 53 /Pi1 put
+dup 54 /Sigma1 put
+dup 55 /Upsilon1 put
+dup 56 /Phi1 put
+dup 57 /Psi1 put
+dup 58 /period put
+dup 59 /comma put
+dup 60 /less put
+dup 61 /slash put
+dup 62 /greater put
+dup 63 /star put
+dup 64 /partialdiff put
+dup 91 /flat put
+dup 92 /natural put
+dup 93 /sharp put
+dup 94 /slurbelow put
+dup 95 /slurabove put
+dup 96 /lscript put
+dup 118 /v put
+dup 119 /w put
+dup 124 /dotlessj put
+dup 125 /weierstrass put
+dup 126 /kappa1 put
+dup 127 /Omega1 put
+dup 160 /space put
+dup 128 /psi put
+readonly def
+/FontBBox{0 -213 987 680}readonly def
+/UniqueID 5018946 def
+currentdict end
+currentfile eexec
+
+80347982AB3942D930E069A70D0D48311D70C1E2528F01045F8CAEC9829F31D648C8D0A29EA8
+51AF41C327A0D569ABAAFE5AFE94DAD818C312D3CEE72F1ACEA0B701B6A5608521A2866790BD
+D5776D6CD0C7D971B9A48B96AA970DCBB8B76EDCB90DA356DC2529B665EB4BB80AC4F5B0F4C0
+ED76861E399638AD3DB1BE4759C78D4F2E81A2FF688D366B91D729D63AB5FC9556FE10A07B81
+904D879A7446DA82DC107FF41B0E3B7C2245D57B2EE9BAB31ECCFE9B79E3EC32CB1F10C622F4
+BCE18DF0E5C4B98EC714593D6F127C5CF6D719A79B83C627433D3AA39CB88EF85D274184C4B4
+C46CA5B496F20460ED75CCFB3D66073B710CC1AD2F2BEC4AC64065ED5E03930ED9EC97810F36
+845DD5048D90D724A88FD3C814CE17C417C84BA45C43F5569A4D73739F71544ED91C657705E1
+31F4D0C61752509FBE0212BDE9C02A833910DFF28F7C53F64B032C8E3CD2BA95C22177C3E053
+2F8699D106F119B80549C45726D793B9AEC38FF4C3120C259083FD13C644DEA026E1E7C75DEA
+2EC2341983AFF4D712C27C024393022797DB1500C6543D620F20C9CE973EF7D917E7FB3E6CFE
+E0999E06C9DFFF2D01BAC5B3BE0C47B2D5ABC02E1F0F383588F430FA64BFD5250E56DA323C91
+F033C8F0F4E0F9CBB36EB8D4D25B127FDA1BB032A7088CF6FB34B617290DE038198297F2AF32
+3602E5E96D475E4678E129D88AA15D5AD9CB58E244028CD8D9A8210FB1AECFC3F29299986C1D
+F1CB3FFA0FC203626E8E2F6F3A6AB198963ACB2B528D6BC06687D59EFDDB9C88535C1C69DA5D
+81812B911C5EF9985179796D2B2E4E92BEEC47A4075E306C8D26431D8E0732768DFF70EF2270
+D1FDDDDD4CCA0F209AD05C9AF2F26DA7CA0ACCCDAC0EA4F479B548C741193594D515F614BDA3
+F394C77BD7296981AC947CA0D6D6CCAFD9A05547B28F0CE449FFBDE2744249AF134A1D3629ED
+FEC122C615E4A74067A7F8358519BFAC0F31D1A46D260A3DB271750D02CD6A12D019AB6C1C2F
+9955CA205F12D8A03DE3203BB5EB869ED8B66B53D1C29EAA26B4D20F9460891B018031BF81EB
+A788B77CCCCC5FF99ACB5B025A4DCBAFAFC1B34BB2ADBD17CDD741DA586AF1B784CF74CF8860
+3B20D68AFAB47D21C1A0C6BEE297777DB1A8231237A40EC89AA97CE1C848C9DA6804D3B98C11
+590B239616E0E6D668FC5B987075D77769EAF4877F1A359217B40731293574EAE905BD7A5C46
+719EC7F8A97FAC1C46DCD76B0344E8378FD61D02C9905B194613DF280648E2F86EF15A2DD8E6
+BEC1CAC0D90B8302B2846127B2D50D8FFB7D210C7826FDE88F2D165FA6AFD755DB04910140E0
+70126A663F3D57EA417ED6D2128BF21A7CC2911F8BF0F2668EADBE8E042A1CDCEA38C5C9A712
+26F6F4EDBC85DDF8C25D80933A42F5F303E5495C247E973DF20E2195B07B60657205DE149D86
+DBD56BB2594FEA81688F21573A8210F6FBF48C82425BF58215B3D91D3255012F7B2BC17357BF
+B35CD40B0C1D5536CDE7BD0B29DEA7674B32BC83CB453BBF76807CF4A5AEECE57FAE3D291AE5
+0098B85E357E9606694FCFE15CC48406012BF12EFCEA89892D1811B5EF93ABAD0E929160090F
+AD55766535E605ECB8381777DF5A2AC4A3E332A7E1B7AB9713A37619293BC7C8A69652EAEEA2
+9721F81FDEA87C0F323FA843325904149416D36CAD4BF4FF795DFE8F5F9073474A5CB2A662E8
+47B438BE9CF54058F1AE7F41CB8F298ADD3159AF95A1CFCE85FD603ED88F301B04D4E8BB4024
+D354FA4B27711651101B499AC32D80E83E0BC11535DDD465D0C061CC7E03513CAD0C2943CE6A
+A5B6F9AB3133108A0F41C3AB724D46E10838205287C2EFE6AB5354A24CC5B7677BFC15E067A0
+FFBDE26300A5962A8E9609F4EA1E06811CE576D04DEB46C49CBE1412C01CDEF6DC45FE015123
+E1CAF9F40FE635F580687BB54E1D90C4F19A3B0F94E78D2820A4FA2D29E40D53C86025AB7B83
+43ACED39A4456E73347CC33843F7B1C7B6286BD315C88E891E5600E9140DB753BF076226CC23
+2786E952176F8767BA9F124FD73991B3D280B017AB0064C5EF5BF63267D054C69C9F08B50259
+6475D8B5083A23488867DAD890E37658D1407E6DD0E225280D43B36EE8FA7C6AF944A9A92BA4
+55F3452D2781965DF4A67FFD9EB6F2C7DAC8DA44B2655D8AF179C50DDA090970D9A15F7A742A
+FA84435C72DF5C6627633B7ED52EBD8C4D5C835C93BE5FA7CB58F43A930D22513C88FA7DE196
+E7CF4AD21F59E85E4D5A1E45DC0807572D81C9A863EFFD54BE878B4223DD885187233D71B713
+A4A4D49606AAD372CAEF27DB943CE13592AE7B60B8355C4D4A4F65BF1A7292CC4566D8DE3148
+6FBF77E4C357D7F9D152AD67106F4E73C5D718583D7329CB086189B069F8AB1D372015A8A37C
+753CE0701EE56F35BFCB78C3337DE4889AB74EEE983A3C6F6987790FF1B3FF67F4C95D32B524
+3A6557171F1C4A8E7D7113056E051964883404E5F748E060A4F2C83E0B909AD58E90E55C8201
+548BBF6BA31C7861B79995181E0723255A769DEE58BB098091A80505C59E671936CD2550B38F
+F4AC0D4C8A2199EC15311FD5A7A659C8028742CF72A318AB3AD7171D8C8DB3115D49290B63B3
+C49330B9CD1F0DFBF5D41DEB9F5AD6FFA10DA0478239E0EB837D8A18FBB6C95FC36478B7BA9D
+F0767283514A2317D0C868788D9A77FD6B341C71B9A3F56CD796727877DD4052CB9D00EA8E6F
+B4D7344830366860D0FF5E42238C0E7C800DB4DC9ED75FC3104B60EDE11C7D51EFB2D54039A3
+56F6FC3362142F921068B5894FAF946F0391C009EC59392B7E3FD20FD42EDDAB0E92E0232701
+04D80365D513007A85B65A08ECAB836BB70D538221C6167E73E9B60B22FB122FF5F15E77B398
+43762CC2D11F166FAA06F7FB61DAF0A05A370FC47602E019A4656F585B913248070FF2C8EC8D
+25AEE6FA7062471A562AAA8EB026260A67221E77F05D3EF6F79C2440F0ACD4AB03DA13405FD3
+39E3BC047412D0F503063F98B8FA0E6BD5E52EE9E2C2BBD3DDF5D07122869BA8F08F8F127DE4
+EA963E21B2DD27E050FDDCD751008BD32B731480FB0CB7E81D25B78F3A85B26EBDCD12062435
+47D82E7AE4AB9D573BB01EF4E6482CE8612EB67A1237B87D7515B51E1A218CBB724E745DA73C
+72DCC1ED013E80D4D95C303642D0DB099158D108637EBA62A28A5E7AFF8DF1AFCF12E29455A7
+4EAA4C8FF91A9AC69E20FB107D6A4192743026FF10F2A48E3C83A06F3D8BD3127E3B9BC63324
+DB4C7840B91079D76A3163FCD35B13911A7703876B57331C6E67AD3A8177BE5D0F0519B5B7F5
+A9342FDE21FCED195C67BEF73C786C86F6E8E9E612A1467C3E1B1BBA763C882549017016918F
+0AB2DCB6A3FAA0A25AEB632B2E5F5A01964D08E86FC8AC0E219AFF0802E8C561743CD4BC2558
+39707BDA8D0E318E257FABC2AAB156344DE064CF7D02F03956B02DEAD4607975EACAA0199AE6
+71FF07042879C5E604231E5700E13BFCF142361851CFAD31F6B90BF4C9677BCC985E2A6BA4BE
+B0D492894F41D089EE969E7F59104AADCF79764BB5BEB1D4677A6D445C53AC9F9608183784C0
+33B991668671B222BF3DB336268DEAE34A12F8C4B27C5C38BAD94CCFF3C298D34F56CB3F53A5
+DF8A0FC9EE29B8A55B18843B9E53F5EECE43531B5B09DD483D831425648F27DBFD112C768176
+96C6A59AF58B35525FD6211D839FC4934D935CAFED49D86A0BB6885C0C2744BF6F59C3A84F09
+E1939B7ABA98844A9FD1B65E061EDD24ED129FC1E6E680549024594215FD43ABE89A3A2BBB91
+2D8831A6A571345897D49C6980EB77EBD00417EA3FE223F51155FEB010ED274F27DA8CF2FD8A
+A2E2BA0BF8DE662B7A5A7051B4D4CC35F0AC975B9ED28609644F4BEDDB11017DBC8A29C86B4B
+20328A9D76664F48C939BB0BD68170DFB6302F690570D02ECE0E08BAD62CA854F97D0E1B1351
+53EBE36C7FD037EE8F6004F535696DEC5D6F857038774E4A0F706CF419C4BE0FBC39F572DB79
+39D223065275454F26738DDABA3698E3CDAF49A2E932CA91BBF8270970F6CC22E313F40EF677
+71E3EBF14CBDCEADEC46D026D8746AE0AC3CD0EFCB874906DD3A861B04550131DE1E7852B76C
+5FC8408A4038E239012491B1517A86CF14CB7E1A81B5C34F9C22ECE6C1C7DAE7363F0D200FB0
+3DD93D80DE49107E89D14B91CFF6CDC741C6BED3790FB03E484BE455A4218E9AAC7497C7B691
+4E0F108CC2995400F53E88D9650A0080E00E17AB94B4A0DD0F0BD227F85F8673986F8E2272B3
+C724F204565FE2A81A5B2C33FAD93821943A280BC4305108B0DCC7340C65957FC146CBA4B95A
+E9A4415FC38B87493816AF1C4602DABEB64555B225B9FD1001156D6C94A1331258227CF8C043
+2C1EA27DC647EA7F2127A2FDB4AAB8203D85CDB25D2B057EAC6AF8D198D0CA763056C278C2F3
+A06513175ADBB14B33DBE438F9D7706C241CFF6626D750D2239C814E61BF1C6B278B3A2CF8E1
+5B2F93E2F2339A5F3FC17EC74FA00B2B4EA34379DA24058F4CED29453E59082E11DCA4C109DC
+020C7574FDEBA6E6A5280DAAF1C8330AD5EB604AE9DB28920D86CB4018244C2BEC0B817651BD
+65C7E5FB42BC4478FB72E15CA9EFCCC083CBD1122BBCD7D168FE296C86DEF11858F50ACB2C97
+5DFBC19EA4420429503B110B738C44E779D79BF2E0783A8EEB14C507ABBB7ADFC369959A2291
+904F03FC9E8A4D8AB895AF131D1879E33BBF68FC8FDFE22F0C801363CEE4C95286317E6A9055
+9456C766BFC5B4B08B765722E728EF7970E83AA83A67481098C7C2353BBDF25CED5C9AF6E3E7
+DBA81D4E95D52E2009EA9CC386322154CCD55B7AED8D1128028E8C31BBA7A73642A3FDAC7BC2
+2861A9B2A057F0E283B8AEB8F0CAA25439FF63BCA1B1EE1DA65D9D92D2EA2BF7AFE23F2B7D7B
+A5B30104A2DAAC28651AEA8A603A2787FDC6AD72560B64F8A2BC8075ECC00030BDB8796E1CCF
+EB6D6D95122F5C5A5080233F0533A92A93197432130625E00C75947326A72F9457F0883560FB
+465F5DCEFDF279E5BDC645A0ADFA6E7C810526D4834D34317175BCF8F9E96D92BEEF971507FB
+193E027F3AF309E5004CEEEC6434E1E5416B6BE2EE39658F31572514104E22FA6465A76EF978
+2CF7F94E9AE9AD133FE793B3CA411CB8DC4FDD0824567811B4A131046C7B2F70D28422428F57
+31D15AE5DCEE894EF5E8F882CEAB923470F67EDF67BEA6E72645E66D2406A9F3CBF7F4DC7E9D
+71F22827A233C74D5781D528AB240E81B8F3C6162B7EB8D7A68FA6BA3EBC23EEF184B3FAC790
+1A38DCC662A18344F33C7349CE7BD8224A00EB7B039AB8F316D28020A6CAE42FA2DEE8798F34
+131A928B52511C1253683BDD9273862D02A693B50EF7FE7CCA8898278064620B3D460328FBB8
+75B4B2BAFADE2D784FD517F2678610E2C7E90C35DC082787537DC1DF0367F26992E03A3D3FA5
+5BD62B6B4D61E92E3CB9130D22C2A7C67A56050C43FADF7EF1962C61A70E98B6FBB5ADC5F014
+A5D42DD7B5C920A43C4E9E6ABD2F0F893E82E6BB4938D197F3FBAF120E79E105BB002BB9F981
+224763EA0FCD4018191497851C1323A85AF4E2022FDCD7173D3B590D7035FB65AEF28451B132
+24A79576D088823F6FE06152AE0F96E05A42532E425DBFCD9C4494C0E912B93AEB4829DC6E34
+ADDFDE3AAD7CF31E4CA44DE6D9D67CBA2516243F26DB4C9AFDB34A0A67F91CC689585E03A250
+5132B9A05285862574D7D3BAAEB1CF9A3571C147660F5E84FE69CD5C1FF8908D29415EA7707F
+C04D0FB46425BEB9A1E3289FB938F11BA8808072F88E2EB5996CAAF6D1B90A5861E0962F3809
+706659BA963123221C2E7546417CF3D9BD4EA07FC6F3C212860CC0E9A5ABF469426655981A2C
+0B54268DCC635B2883E2786FC5DBB46E09A5FE329FC32680250B744AA0D80E51C3524A8FBA6E
+31C8B0899065ED33192C796383AB20FC7D9A9964EAEE7F9D7467B57787DD06C212028F08C538
+1EAEA92AE48A38BC67B9AA3C54009BFBCAA6027A13915EABEBBD3EECFA8F26132EF5F72C3491
+5A4857BE9B1457BDD1E04FD1E963BDDAE7BBA8C16AA459BBEE2ED112D7D7F63EDC21082BFD7B
+702E3E7EC8241907E4176AA0CC537EA5C2DE58157F8221C7528E26B356188EAA7D7B35F7D721
+081C4406C96399A94798A6E47C443F8303B807BC8335061EFF884B59FCCF814B973600658E1A
+092E5F0B9A16B964CDB55D1AF2D85B7534F85A46759668E472231EBD0B71B3595D5E13CA65E9
+2B97F882AD6375B0E8133C00CA86585A1DFE5482302B012D5EA2526F1A100BECEEAF4CE9D5A7
+C12FA5D9C951A2DC27B0D8CF87A1FE8767BC48594403F8E1A39D32D4AEA89D666471130A500B
+2A0674D531FBB95F28C974FF9E76A2EE9D384373691772CECDE7CDA6C201CD6C4C29D5E15874
+F91193220133C0CDBE8B201B854D568FCF73B3964DF7D0EC3D43DA92D0578947D2B8276C1A0C
+50DF18572A5B96A6EB90CB26EB6A11618D6BE38DCEAF72D19DE63942108BC32415B006258C9A
+5AC732112E7EAE2CB6C8DDEF064CC23E2FF05916C6B79B17DF6FBBAC607E056EBAB1058D96F2
+A3472651FA35C4FC8299847C22480084885AE4E60763246A7763B05FB45CC2C8197C3C69E573
+E7150CC2AE980A165A159E7D4082D10DF64FC4269E7A71784161B3F21FAF7DAC3F1F74532591
+9C5029264AA34F7D2CE425D2C2B664D8AC10B220ACB4BECD94A935CCB220785DF617F156E310
+926D73B87B34F9FB33975EC74278D0B2FF7B8D9A0A93CE6FA9F7D722F894A9294F34CE8242B7
+20F6E438CACB7DBA554E29A319E3B54A7B6B6FE13FEB357D42FCB140F21BADD8BFB0690F086A
+3E4931BF0EA1089BB7460744A36E33DAA66CCD029F30F0E7607D8554D9A9C7405EF8DB9A7EC1
+3C5517BE5094C2365F237CF5A28BBB49F29221A28EF95032C8EB4D4283C233E87D30C12254FB
+084AB93D970C7245FE4673284367A9FBDC86EFC2EEE2998CFB9E9B60DDCA3EA54259701CA4BF
+C7AB830268065C19A64F3661D4DE3968C8AE46D321426A1970F76568548DBA717059AA6B3D46
+49322B7F5231745FC65F73F383F711655383449AF2E0E99982CC796CBDCD8BF628783C3DA0F1
+509DC884EA0639C8FF8F7CDDE18820586D251166AF758D43D2DB9870449F1676B66CDC0C87B4
+F92EA1A6BBFCF0639AD7BDC990ECEA0A0F893D8E862488F28D35F1C83C2FC2DD164C8A1CE27C
+8F0BB27F50776F2F30479C644618AA4A2E9F7F32BB7AD6A7454EAE1EFF844727A8189848EDAE
+28BBADA3803148C563AC4769E8F7C3E109BA1BF2E8D1FD27F3ABB9A9A332C0A8D3980CCE846B
+C64F6F598B1C048D2C29DF51E48AE2DD478B5132ED5C28DFC08F350834CD2CD7031F11EFCB37
+F8D8A26451A6578C10E4192CCE42230B0BD398AB2E38D45CD4F5FDB3EC6AA7A244EA0AE43BA0
+ED9B2E8712B41188FD037093BC9E16534C61211E36F21B2B69938197FBDBC459B02F950847C8
+941F7246177F2F6705BFA5A454BC8A3947C7FD9F70F41D2F3A15F6BA14340C4B1F1D97BAD850
+90AEAFEC1C1D79D2CFAA9915BD79FC3554F37CCAF7C89E496B6A8A0E641BE345B1F51D4EE651
+B9A85F56AE0515A25915B3F53EEA2DF8B78E79268595CCA76760D9509541F8641B9C455D23B8
+44206901DEE2F78DE37943FDE09A02B41A05BDE3AACECCB1CE6AE2E57C2F418785AE69556273
+F27D6089B5D1F5F3C41F9AA0280479885523B9614981FB6C0FA35AE488402DD9666F2F500992
+DE9DB83C1474D2A80F04FA78440674BA1F6A0561F2320716245CE4D4D34E3600FF4B880B02B2
+59B4F1672D714A8180C63DF5AA7A6811144CF3F21D1DA2F23D9ECB249FE4E76E87C759CAD386
+6701BF658919A9DD28ADCFA5E0CEA43E75BBC1C4CE94189FD435F8098BFB3D39E7736C45282E
+B1575CA1FF186B9279BE2C61582FFC713A77DF22569C456722A3DF4B21DEEB398662144291A8
+74A104DDC60A521C723E89555DD66703CD79F4A7A07295097CEDE9F33B16C0BEB690B5BD379B
+9225C099B048568A4589FD07570CF90FC6E8F0EFA16C566FE736D05A0E104AF10D2DF778057B
+207F328EEFD63CDDF755F71CC5BC39B6778943178B172CF1F596EB17C89B9272E99B0069294D
+D6C29278F3D2C097069A51F03E22B81596FE5A77931E436E0B06FAF45D2C383146C56746773B
+63BA9AB3E49AB94F1600D4C0B15C82FDC17A2A869ABDE1FD79AFE9ECF07DD4241CB49DE6812E
+DDCFD46F6E05C7FA95D1D1FF0CFED15FE25E4613C623E4B17D041179E943C2ADF392411B3B70
+1868942C6790089193058ECE47AC2B29BD55AE0A401677D1BE3F4214B0896065991F5D8595DB
+9AE3EA4813F35B377C6E95A6156702BC1F675E7A88AFBCBA6E9D0ADE968374928418149B52C2
+05C306DA737D78FCCBFA2FEA01F09A2F19AC9AEA0D8878D5D2FD4F622A5DD64635E3B2E17779
+EF3BCD3C47466078222AFE4498194294CD1CB4D7DEA3F522867FF34F3A294B2FC69AB54CCE03
+54BB3AAE536E884A908B0EC384A0CA7DEA0BEB5423C08F7C5DC186E42410DEFC4DB8D51F02A6
+82C529439C3E3EA35552F0B459F0060361A9E695002BD293DA7D2C02E1B0DAEE6901CA644BF6
+141290A33B8682E03BD0DB0F5138F86868FB2A0549743AF7EE962F9DF241FE3A98A2377F158D
+EE435C64E13DFF529D36DA039DDF7B5F3ACE1253F3EAC1549273704907EDF51576CA85D4A728
+F0C3E5381D06C5F7E052C08B75F64072DC77BD9C42CA097227A44C3F7A61002C5E89D1159784
+00F3A736E013019309C841A6896A885F307D1D7215F39D088B8E37BC61F08D7661B6EC99F956
+D65BAC784CBDB8B80F0C67AADED9E9E5E4D8C6E755764AFF57BF01EDDFEB8E6922B70EE999FD
+A1F8B8309162E0885CCF0977400FF81F5B17DADF1953E39061EC7460FB06059E42BED7A2573F
+1162152BBBC61375ED90F0779DB59B287C8EBB701A5799694D591B809E3EFCFD4BBD7254822F
+4CC6C627D70F22414D1974EDF46B65BB1096288DF0D9EBB03E3821207E3C330F968678FD1BCD
+697815CB606A7B596B030E15FA11BBE9B75BA02E0A70204E14C339C3F17EE4B6801402AF29CC
+A09E6ED34F3AE9B46C78C54D92EC5B26619E721E55CBFAA4EC6085B4622F004D29914E0E7516
+10548F3AD23AB0570A8EC4F3F6A4CF0CBF89500C751EE8ED1E2222B447CFEB96A555256A3666
+659A11323F957AD376EC8FED66B381405EF270C7E888DFFBD36EA2EED15E8AE9F56EE6AA5736
+CD179C71F015625AD20F48A2CA9787FE4723CF9342909450D9920C0733A5FBEFBC408D3878CE
+8355D805EFE4EBC0A6FFE6DDFBA64ADD9ED57411D98A9C94E5B76D465B8753FD409E748D7254
+2EE4B48CA6C2F0F21F0356CD41C64B0050B02DF20603FB71B8441D08C0B7BBDEA4B7D77D5390
+296E8410184B9529A698D028CFAD9FB9A476E9E22E93761CB2A00598430AF7FC18B2574C4551
+7465B6892AACF6E5E7B7D49C0FE801EB0D5E91A3ADA03C997B8D106D0FF348B1C028BD333B2C
+AFE17304FAD94CD34F29F890E59FEC18A7474152596EE9971087C05C6E3AC02B66BF10E7A8E0
+37296B4F3B15F7312B81EE170FCF46ED6F6CF323CA8132CAD6C5694C52383BE49AFEDEE87D41
+E9770BAC679C9FFCF6337313AFCF77749BA31CDA260AADF7E8D901ADEDB5C5E9D107F2812F09
+2C552A4BBCF2C19AB9861751A69A05B5E846EE90CDBFBD17CCAD9CDE772470A1EC546C2A2B85
+0319C0EE72E0FA0C0ED628DB2402F755DCCBA80415CDDF0963AD7F61CB18C9EF41A53A1ED0D1
+B4596A6C2F0C790DEB3141C572A9ACCDF80A621A3F7D32051E94DD0E76053F9466AC6207B2C4
+A2182AB0CF0914F5431C73CABD9DCC87EE2AE54E888BF9ACE0D3CE786824069A70A69CC18B9A
+14B458C4A7BB0DE1092C70ED33D294D16EDB8467DEA27B31BBD06049B511A6B6A81FDC9975EF
+949C07A1B97993E0153C310BF7B9103350437183DB224EB19193FFA6518D97ACEAE1FD9B0557
+90B101A0A75DB04053CB4C4DB282A7342E1A57C2F97A9EC04EF07A4DE01300CBC51C2BE078CF
+6097AC313E97F816CC9AA854A4E691D97B894EB9AE630B6BB676277E01BE16149E5E66B82850
+4584290F86C50CD4C3C115955DD6FEA544C8672D8FFC6DFC9AB940EDC3A37D58D1627FD3B100
+1D3FC2A67C0129FE64FD8ACD1395F555E8120E6AD855FED3F8DA57F850C6506B4BA17C9984AE
+505F026F25B61C0CD9C6BDF3C83A11446E11BD3C60CF67C45144C7457D4C0A51667315C48004
+CEFA327E35B3593B568C722DF9A67DF323DFC13FD665CD56DEDAE2EED49567C128F2D1E7E485
+C1658B36441AA5CE8774FB11EDCC4994E15834C59397F84A4295EE44F8B8F71CDF5773AFED6D
+74A42461C66C3CED2497F4527C28FC763067F082DC5E8A89242645A37A9A946247BB821E8527
+99B3D3AC1216A7B311DE1B7819D9A89D79878D877015D5ECC1410E380012FD570D8A20FC64D7
+FEE86025FBBBB5D6E9FD293226BB406570C32C2A6741474E0F001A5C0180DD32644B61ED4411
+5A018EADC5A832E1DFC7A5F8F255FF9871F4C959F23A1262F254855A44B49CC888395AFF5717
+AEE21A2DA5457D419A04780C2609DDFE2424D9B96C6B2B52FBDCBEB9CC99D1A9E224992F71B8
+51D694D99B306766E6C1BABFF7A11A3771321066FC5F73C334091972E0558392ECDF9C099B73
+8CF53BE2A04FAB67BE46C651C1FF3A6D19ACEE84DA8970E8C79CAD04A11A474B7FA560C11844
+82584A334B0217C22AA75C2FAB7C470CAE49C58265AD543A09C9FD1ED4ED40546F3138826637
+5DAC12975D10C8A4D65DE6A4166943ABCDF0E9A72CFECB9F2E5F8FE923108150201A812C9A8C
+33FD567CF1B65978AAAC11D6CBD208F08758C1F5D9962282296A84B3052D924F25553D58D9F1
+14B88FDE7AA71593B0B7D01ACF64864D8A321ECEDD1A1AC4E0C381552E581B116452EF86173C
+AE8F26C68B3B11EF710BCF432AAD4669CED707AAB0886E18694B0CCF1110D877D6CDD06A7B75
+0A4B7FDDC3EAFEA3F8C6A5E74A75D8DD8E4BD2F8033BC913468318D799C95D8F980F450C6C7B
+CF178BF622989873D83270872C4C4004F00830B720EF4FD25A0A9C2D709B34EDBD8071036F3F
+B8CCE42124C309009C01167FFDD0CD902772AE83A601904EAFA3684464DB245515D6AF6A1A2E
+5AFD0B90F6D2C121B4B86CAF7D801C4FDE6A2CE664772F092120EEE81A93D9E3070F750E4809
+1AA0DFCD366592E12D17B627514C9F00F5F1858537DF0DDB2CA4E3BDEC9CFB76FB1F5A638E3C
+7D399B369F7A003A55599EA3C1225246BB164A7EFA2DBBCDECDB3A662ED554B41B63E16A3501
+98F19B7B5BAB796915685B88108C713277B6733733E56EDFD8DB620781262ECED9875A756D77
+4230969057B06E2C33D3C7854F1ADBA2EB15B8A9DD3ABF30D7BD953DA804B83125D76BEA7C1E
+0EBC885E07B4F03F1DCF33ADC5FA6592DB3B0E2B7100BCAB89F14D997D6E9169F581129DEDCB
+6276E161AD6B80BA0ED346708EC2E73B018F923A6A2EE7282545C7B929A977007F0CE8BBE450
+940198D3404CDB88972BAD4296E62266672A0AC99D38C68DB786E3872A4E1B19C17C3E1901BC
+B8D87785FB5EDA9DB640B1124D430A6C90F3EBBEFD70CA6C46792CB54037BDCC4C99430E4488
+EC64EBDDABA17B58098674ED45E0FBDFA2E7E8E99E9BF853FB2A4C12C5988552091832374459
+28FCE34910336AA490FDC251CFEBF2A95B38E649F050736208BD2DEAF23348B416C9765500D3
+678EA5649A2F8498A0B8E3888A168AD93CE3E3B1C4238A149A7FF1DCD8C2C0100034B94FD42C
+1C33EE40BFB7C5B1EF47B021704E9A1839186432AD1A65AE0B2F2B899DE7484F5AA106804DD8
+1F0CE6F89A92720E4C38C7DB42817F0FAE2E7675B3B166A81B91F91E84A62B3969BE8A82A5BB
+80A4CC87BDD4C3AD0E55EBDCE59BC9C84F049B68D9E4069B06A6FC4C7C89189EEEB70BA99CA9
+0D003FA72C8A17722015C2E47C36F649896C0F7C19C0DB88EBCD0352CFA77FE21F6A4B949DF0
+64847E1CD39C9D00E047AF4F5733955F71BCC7FB34D22D3C0CD5EF7011A97258B07569C68CE1
+536BD1C8E0864D8F5329BEBAEBFBE44599C3BA7680FE07FD3413C5A86893DAA16F77E167A8F6
+CDAE51C18E01F1A15C622BDE3C52DA37FC70102533031F914FC70540292EA1EE75C22BA10F6C
+3C6501BA9F04F46B8F15FC457D931105CBB354828F7891C41DDF1ABD192FF5A912D8E5E9B0E4
+FC9D7B729BD63D0E7398A8E3EE729137D53C8E716563990F9D7A745574597777AC286ED35AB0
+F6571449E7D5FE6B251123D54D968F4136FFB04AFC97CCB5BC6C5AF8694982ECF269DADC8426
+9465AFA8247C099BF6D8B76F09003FC9450F12BAD9535686CA32CC36F0E5FA4E3C809BD4681E
+D91214DC9A30796C3C854C051E2022DEFEB689D6BC100266D0D268FEA73A461B56228477AD34
+66DC50ED731F7146FDAB4EFDA869F3A28AB9D380AE308843CE4EFC29304DF9F9AEFF085335A4
+803BF0A8D69FB9FD0C2C3988CB136BCDFA47E99BEDAA6EB73EA3E996CFCD1F0B244AC604C280
+BBD6EBDD6270F3A64FCD0A18C90FAB3EA578CB79465BB6253FD7A45729429A936F58CAC73F47
+FE96920A21E1DB23BA1E200CC47890899817573A5C4D059194DDFEA14FDD8BEAA62ED7D7FCBD
+CBAAA75E5A225A74EC2799AAA1E5E27127FF2D668B13DDD330817D292F650FD0747B3E403A1D
+C15BA8BA9A86271A049C8CDC5C8CA2C231EE4287B8B6AD1D1A46BACB4DF6069A577E8FBE54A8
+0947425996DA313C2BD0FD12049BC24397AFD1C0E5BE145432DE54729D09B2B340F6AE470F86
+836B42EB0E46B0C1FBC033C0A9956681B243F7D6039F0F9EEE6D44130400228C48A7A5AA0A10
+22C7E141A6E9B618F6EF01DFC0E00D8219BB749352D2F6DFBE8B9018A5622216AD49C2894600
+654F6A34090AFA712C2A343A0FE43748A0F04044D5AB485FC474BEC3E2F9392AA8490ACD52D1
+255FD8E239D4415BB2C3DA4C38D68BCB36ED6E84B292EB09347D063FA852DDB16174EF574CBE
+31BBEC0CBB5C121A949E0C191F86F29A81EA0C9252AD1C8E6E1C3FD7F8D114EBCD9501251758
+4C802CB3C98947C1F661D39DF1A1A4D327D293A088F03A683702C80E2303AC5E78E1CB295704
+AEC4326C0100495A79CB9007EB715A8CEF5A1CBA69F8C22AE7F60027C39C507B06E2A1D85B76
+087BCCAAF3AD091250D4976A0AABE280EED51F065D388BAEF2C4717673221B7D2C529771644F
+05728DB0E647D3A9654ABE37E90B27B8B1F64CC7CC44AE5215491A54B16A4D4D2FCECEBF8812
+76633CD36ADD5A39CC58E395095B338A42B30E960A7AAE507AB018474EBD4D31DE34FD580912
+059DAA8D653D72BE8C00B29629F67FD820E7DDCD27A834B13482D9BD3CC73ECF907386E58DA6
+9E3405BBDA49CF5D289CAB230D1F12A885C76D9ED5E6F664537AC268F04096F405192F734DE5
+18E3EE750C0A4A59D570254DAEE61B1FF42CCC72DB585677351B0BF64F66940E1AD956768E84
+E38C85A89F647BA5B2C585E9F999E3D2CE5EE8D2C952E429DC7F055DEF3A814886CF49AD6BA1
+C891B7A3E3BFD464BD9F8E78B8F6E89E4FBC94CF284644788ABBC6C7412C2B4FA744C0EFB31D
+93B8B1070766F2E7DA2912A075507622D04BEE1853BC9512BEA9F8F1921FC730ADAF63C8E34A
+9877AA60DECAE43DCC128941F7F1372F164651073435A2F1F41BB598277F7BACAEF46382FD34
+C4E12E29DEDC340DDF9043926C00A5063993AC3918F4F3F459EEBE9D47EF868AF77F3B8D841E
+0F65F8A3A31A65AB20DB5B6D48A96B2E50038C35484DB0B6724D29562F78312E184ECE38AE5B
+631F0816C2C8261B06B6E654434FF4D42122F225FC0B199C6AB1943AF9E2B25151D64537DBC8
+CBEBAA55EE7A28DD0F194C512F28D3BD9042B095736E306446821E8F485B7401D9FC86C39A06
+1289B17F36EB173EC2772B469662E5F0F91301C15735F092D436DFB259F2D7EBA9D0A70CE7C6
+6D120A503D62CD6CA034FDD4D788ABD214BE1F48F78AD669AB5414E7BF99922D9A25404232EA
+A88E7E154EA686F27146353ADE207AC6681EDEE54C78DFF47FB22C751236DF01774D20D692BC
+218B8B2254F3FED353B9FD0D8670E19448F527CB8D1929A86052BB51EF3EC7CFB53863F2C5A9
+EF802DFBC4B1854251796B564EB7476B2FF6B6AB0CE99BD25E3844F4196653D0E11AE7404CEB
+7E5994B78B1DB6E3AB153B47EE62DD5E4B384A511C71C79077BB0329E9A41E2D89913517A216
+DA292797B86951CC8FA43FFA64C7D7C48C1A00DE6710EC7D8D17439074ED3CD7CD3DA79B54E4
+247EDBE6087D8F71A1F5215DC2D35496CF3656B7A1D28BEB7F023781F1A68BB16356B1CAB4E0
+DA51B5C436F3D603D8198808461063EABC2F7D9764442595B850BE047EABD819B75D6ADF1A3F
+9E4591777382742521ED08FD8A3D36594D288F2DE8363E893BAC702DAB04F0E5505FA54EB416
+3508ED09A61D284736D91683CB9688A3CD16637F71672B35A757A3C921BBC9E700EE41872B1B
+8679ABAB584C72C7EC17C870CE0D8FA5B13DAB0E5B573E6E84E8F6613DB208615FE69E0EB951
+2032EDBDF33BA8FEA1EEFB0DB8FDB418A89B9C5221D25D9BAA0EE357E246C45F21FF73741F72
+A29A8F5EE9C139FEF8357641C900F79D648B201995D50D6694EAB86CF5B53141AC7F1FF45277
+67654BE31EE45773E48D791A162B2DE625B0A3AE12B3ABDB1B4BA72F49CCCE822E402E174C67
+B74874DD1923810FF1C641CEDCCBF00089F2C5D9D4BD6F2917ACEB0CACFAB51DE810A00715C7
+2414105CDEA8931BBCE2E2BDF218E91532E3CECD704E00ECAB6BD9327BB994C60A9D05532890
+F5C30F6099418289285FC9794D78F02D5032F91FFD96055E6AF3A1879DAF140EE73BC128FE6C
+D084593D925F79732F23CF234A79028F916A1DFCE5F28D142FEBC8448780D14B7769A55BA217
+79DE070A6E9B4C17AD66AF7B7291A4F10AF69A82D541737E1C14801C6D724DADE22C399975B5
+3EC0604FA2F5260042BF9021B2AA68EAE6C7F505BBC213A8F87C249DC89A10EDA8702FA603CF
+4C14F40FD09E9CD55D6DEC1DF20F3EAD890FE2EDD6972DDC06CBDCC09F6967D615E73F3F0452
+8BFD00C9C4926575F6037F858B28F48F2121A4955CE2A1C84EC8C3FBA59949DAC7117CBB037B
+60C2B08FF325F74B8D6D9735BBAD7008B6AE79E8420523A899C6B796EFFC2828129F9674F6A9
+EE55B2CAB086439A731B9898EAC8D7C23B43FAFCD045E69E6C886617C9E999721531E5C78A91
+AD8B322C319A083673F429DCF09CAAA37CDCD31BA3B259AA4CBF5E9A6C70E5450226EF07D7C7
+C297D9541244E6ABDE1E2858EABB131C4E4E20EE1C2B143B9E24B7678DFF7C90481E0AF5451C
+1B87DBB81CEE6AF6219CDB8CF93139B58C39314F530A4A8992D2C6EAC3115EE77F7363D81DAA
+B0359C6118FB78BBF21589B3D7D75834733F8CF23D3E6BB17F6C31F56E5BEE74BCC7C4FF9AE3
+1CB9BCD5BA8BD82D2C3AA80D1E8BC391EEFEE1C00E04CC44134D0F29F1CBE237894AE72BAF49
+061B171F3DD077E5B4F64B3DCD3183797AE3938AB7E84695A9CF153419238ADEDBFDFF7D1676
+C4BA02EB00F19FC1E682B727201C1E20B75EB284BCE2756ED63974ADB2F4FE7FA3FBC117BF28
+14AEA5F78450A69B09BF39CE3D308863636AA4F4DA59115681866C5B225480BBA8FC219DC8BB
+D8A89A891197D7B5773C9D2BFF4088143003EF10B8A3B29C7596D4C160BA4C1D87D3828CB1AD
+A463B35211B11BAD337301B29463CCE7ED6F5C0CA763ACDD2CD4FCCEC6CF0387E0620C7662B4
+3DF04778F0DFEABE49F06B0B2E344D5C9BF59E898771DA82A1D8BFB33E67F0AB0FCA4B3E2771
+3BEB2ACFD2D4EFE88A6E93BDD52EF9BE9E5E93B4B88F3D8C961D3E9E8202D77B9FBFDCFF139A
+00365DB1A7741E9E70FA62803DE7ACDBBE559B968E1290BFEA47816E15C8D2B419A66EACEF52
+A6C71173F5CE6B99C1343C9CDD6A11A729BBC54BF4B14574F7AF4B33DBE529521D9EFC471EDD
+26DBA914DBAE2DE73EAA36CEC82EDE487F709A1A56B32EDD5AE039026D2B57B85A0189079BD1
+D6B1BE32CD05706832A55AECF57E946C4A0DCD4D976B7583A9FF609EA291AC03BB5AD0466ED5
+5C22B2ECF7A573E6120F2478F357E7B7B7476E2B8F00F82F4FE170F3D5D71041359DC21BA93F
+338727386327638FDEDB37A4F10FDF9C4F548D971194CD4109482EBF2ED92CDD3D21B15646DD
+46EA6E010B6B0CFE064D387E9EFBF6236FD618FFFC979D69B8BC50BEB143370E5061B2E65DB0
+4423CE2A8F0C9C880207E78C320241E311CE42C077AA89DD228BF28F0153836DA150332B050C
+82ADB32FEE6DBFDAB3ED18680A0AB9BDFEDCFC2203C588AFFB481AFF930F26A1F7A0326BD1D6
+E786AFE43553280AB61D1B24FE33E7019C045A3EA01E4E8D125ABCD2F09B4F54771D1E94A206
+C5742DB08B79DC50BB5E44549A5C8BA98DA6AF2C2CE3A5E40FB0C94E4039EAC994F6E11AC94D
+E42AC5A57217C1D37BF132765D6775D5D5A959ECDA55B081908D9AE8907CBEC2265FF56DD8C8
+E10732118883596567390E42471A8145098FE08253182C0969209B553ECB0098E4C9F3133A41
+10B15E13FC2AC00F9A247642AE2FF04D096378FE8C32F36BF5F0435D2B70AE96BD9DDC376C2B
+DDFE12AD43F92FF4DD3C060AFE90F9ED2F3F579A54F72F8F8A1246254DC2F879D34AE11C0CB4
+37AFF31E320CC46B2F7B614D3ABE06FC42AE3A2FB03DB3E592F2CD0273AEA93EE12C60C7E371
+2FEDED8E9217E67EB18BD6688B83B75474475EE3A3963117F58E4A8F78129338D59EFC9E0898
+8F35BA35E04B4C15F2384CD74AC955776D883A34B8409F2FDE5335F259B60AB2DDC64629A10C
+67A15FED67DD579C6A1442ACBC0D43F4BD371553E1A16AB01B030274C61D3013A6582EFC2BC7
+5E4E0454A7452A8E22A6159DF3A7EF74DF19DCD3F764B9C11CB9A6BAD0BF2B7C9BA5BB3F574E
+3A9C0CB690E3D49E3ECEEBA3D04827BD87FC3546EF3C7E8155CE4991F501030EA2C89AE5F883
+B1AD24041308517D68066B9B4B40C91E74491A5E772BB452563AF50F190E6EB705180C674E25
+F897930928F29BC68C250170D5B54C1930A1D496B210CE54DBD1FCF8095FDA8B65C63EB0DC3B
+C519602ED48139A09C3291B421AB403C95AA19E3F384108C54C83F3592F1D73D469054E239BA
+011EC3024C02872C2F5F4D6E5B1CE3BCCB92F633D11235E3F8CEF92B9B5DAB50A4CB88A1C872
+7D1DB2B0776E162BCAC66AB3399721E2BD3B58993C386798E58A4FD0E370771EC6B0E0130221
+AF9842295C3AF9C2B6BAC8AF8FDB127D34C0F6BBBB24A9515C79A6695D78E14BCE78FC3E2143
+738BA7E0DF2904498E0214522EE3D8233D5166C6F35D14319FEA345213EC86E89EA473E35AAF
+94BC5C2FFFE94377929661CB1171748DF2F56C889B62EC9FB1AFD06769CC7072CD356D3912FB
+EAFAD4FD13A3D7E33010693C26527F33C27AC8B1DEDC441A75367D1378CD6F3D76B88A0F5B4C
+1354C0456F99193A35EB6BA9B21270ADBD2769EBF66A9E6A023E873F3B9167B292FD95DB3796
+9C9B8A4E33E7E7FEF0D0F0E752E14F0B38B2C6320BD823135969798F4A127A8B7553A04526A0
+EBBCD4FD2D4B01C3438D167EBA0D4DCC11D271B3C48B796B616C9D4F5AACA25BA8CC2DD35038
+95CA8AE322FAE131F8A5E0CD911FE2E77A942D52F35DFA567E9044D9C1B73F8112ADEE7E1DE0
+8834D5DA281E9DFBB6B9C6B71252066584B0D38B40D8AD4369F7AB779A5B7191E56D30DF619B
+00BB9B261E867185E078291D6206B114CE7C63B25D3DEFA60C9883E6BC8C98E3BD0E42EEC829
+C9313E55BB3D702FB1D7B66C8A226B62E8B1DC69C176409E52D85025AB01683C04370AA2CE06
+DBD286C3E1BD833C7FBC75FB26B9B8676B6A554C0AE8870E6921D50A2FAD1EB75C8418653843
+A02990F342CDAABC87E68717A872CB18EE805CF6D093C02E1893F588F8A6DC7894C39C45E1A8
+390F6B76E9D2292F06DA5A3AEF9F0E553F09715A7357A6B6D801518EAE2528D02DEB22982B04
+4D13503EFE857B1BC3D62449440421A04720AABC615A8815817D2D3D8EF337B8D8C0FB7D89B7
+D973CA876F595209E7D41464176C5B3796C41A1CBADD1BA3B5D928819788B395DF9E50C16D85
+8DB9E86E972AEE3B94FC822D91176A8F3B13ACC097BF8712F222C23369D2CE4855C5201C92E4
+60661DEACC951ED9D2C114E06967BB091C5451476403279760E3AC917187FC8189DFBE4BD204
+0774725E8B140CB4F8B4EC17BEA93A8AB22FDD4A0B21A1EBC43C7E5D481451EABC02CE3A48B1
+7F822FDECE44694EC09B0866D2ABA5B5BFF8BD17E261C58A48956C476FD979C40346C1D6145D
+B7F5201BFD9733D1DB645E1565D9ABCC2F03CE5316BB44102C07E12880AC4E9565FB716815D8
+9FC47F553F85CEBA858C57EC7C7A6C1DF4CA3AC7BA4E7E71A0378E3DD7816F3043A78A380C10
+C5C5CDAC4EB0AA36B6ACC95989A5266C16C362F7F17CC3439D0E1943719E9EB52D582E271E88
+DC31F5790D6CA84AC3406B8CBED0E3705CA2616F43A7616D7056B500C7F9FCABF3A5E0CEB41F
+8F9F3879DB6315269E52273C9358ED7D7E72EB21DE208788F43AD9F404B02869BB6B5C73D313
+40C29D4B5DE5229C168A7074B4DD97E5E2BCF468E97FC29AFB055049CD365B273D5DC7F0926B
+7DF4882ACE772FD63A151AF5A0CB9E70EF5F416EE3D17B2D06315CEC1A6B0D96DE9D26839DC9
+E7BA7B392AA4E7197F20FA681FC5478B750A7C6E04214E257AB15B1C7C1DDE9E6D44D604C61C
+5E47E2C7851E4C1C0CA2575FAD71710C35C85B87FC55080D5F08B6640BEFCDF88B427589E940
+442681FCC09E3FAE3A77E4113F29E7F54A8878CF49AA28FA2A1138A521A0658EB07DD2BF6419
+3C0E996EB89711026FC687897F3F7FAE6F540D9537B5088E5C0C16EB9819911CC8AEBE36B36D
+B254E304ECE01D2F3B1277D11A8E2F5ADF183054E8516A0FC40CB03316C0F538EA6B1199C3D5
+6F9C6FA65D22B125B83571A326A915C6B3200DC798F50FECCDFBB826B8A6388CEE22BB526AD8
+834D3633DC50211E933C979D37B11F2ADCBBD6331FEF4F3B9992F7748086E52DDA3F3B47B027
+38DFA6124B9E14449128FD7747BB2E16C25CC8606993A593570742511977847C0126A1218742
+FFCA4AB7A08CED8BB1266E8018710DF2A7312A21608CF2C545340F62BF1A40063E03076713D9
+5130CF04D76FFB1BBAA7EA2EEEA5D9FC691686E4F6338A477E2AC59A108C8F4BC2DAA4456FC6
+0D91734637DAC47B65FD74B9B619B94774D1B58B0A14DD423202706C332133E49284268685C0
+ECDED7F63C0B9D1E16B77CB558892E59031590EB933C2A8B603A1F8B656358322EDC7308146D
+082833D49AE7CBE009419F78623E73FEAFBD092A438F4861B8C07B78DD962CA0C34F82491F98
+14F1925344447712A921B1D26ABC6C89E8DD00F69775E6C0A8C580CFAF9743BD0149A31798C4
+50B97528723DDDDD1C10E79C2F79ECDF1A1479063C6D17B0568B767CCAB08AF0CFDF68BB46B1
+8F61780021A1008B6E7CF21B93347849102AA673B8107D0C34DD29C59878549E6A098E4EB5D8
+E1D532F0DF9B058CD32847171C7617F696BECE34A7B90DEB9AE28C866EB172F876F6A2A80728
+624E027CF5664203E27D34C2E8558BB67E43F241A457A37C21E8E9C55DE5DBADA35CB5D805EF
+5ABB4F422E62BC4FF9EA332C616F2F881C6A6CAB91BD5066CF8E938F5AB5F6365B17D8D02FBD
+957AEEEDAAF21EFD4F94973EF1C00A86CEFFE5E3C27CE6CCE082D0776850AEE702D2336A8A26
+74AFE34E4BBAB7C92B0D512C51734C629845119E636278874501510B0DC3F6E14E0E02326708
+9F66F37433E57E7CA920F574916EDAE9FF42738B14888487D87E744FA29543E1269978D9C6FB
+71BD7D9D6D4646F6C2F702354B6442E1627AB0711B528F67CA90AB398169D8840DFF6CB09D30
+BF3CE8822FC14099C9CE2A1F8F5BB873F11B71BD5DD09CEE0E5F6E14B6FAC5DA098793A5356E
+0C0CEBDC52F890CB295DD54E63040A801DD51A3ABEF3F2226F6D27A5C71612C156A0CECEDABF
+D956F35A5EA4AD07225866EC415211A81957C32771D3DEF24104F0BBEA854AFD309EFB79B05D
+C32A27D5E36A1402772FC5CFA29664BA3BDD1E0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+
+
+%%EndFont
+%%BeginFont: MTEX
+%!PS-AdobeFont-1.1: MTEX 1.1
+%%CreationDate: 1993 Jun 26 10:30:36
+
+% Copyright (c) 1992, 1993 The TeXplorators Corporation
+% Hinting Copyright (c) 1992, 1993 Y&Y, Inc.
+
+11 dict begin
+/FontInfo 9 dict dup begin
+/version (1.1) readonly def
+/Notice (Copyright (C) 1992, 1993 The TeXplorators Corporation) readonly def
+/FullName (MTEX) readonly def
+/FamilyName (MathTime) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch false def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/FontName /MTEX def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 161 /parenleftbig put
+dup 162 /parenrightbig put
+dup 163 /bracketleftbig put
+dup 164 /bracketrightbig put
+dup 165 /floorleftbig put
+dup 166 /floorrightbig put
+dup 167 /ceilingleftbig put
+dup 168 /ceilingrightbig put
+dup 169 /braceleftbig put
+dup 170 /bracerightbig put
+dup 173 /angbracketleftbig put
+dup 174 /angbracketrightbig put
+dup 175 /vextendsingle put
+dup 176 /vextenddouble put
+dup 177 /slashbig put
+dup 178 /backslashbig put
+dup 179 /parenleftBig put
+dup 180 /parenrightBig put
+dup 181 /parenleftbigg put
+dup 182 /parenrightbigg put
+dup 183 /bracketleftbigg put
+dup 184 /bracketrightbigg put
+dup 185 /floorleftbigg put
+dup 186 /floorrightbigg put
+dup 187 /ceilingleftbigg put
+dup 188 /ceilingrightbigg put
+dup 189 /braceleftbigg put
+dup 190 /bracerightbigg put
+dup 191 /angbracketleftbigg put
+dup 192 /angbracketrightbigg put
+dup 193 /slashbigg put
+dup 194 /backslashbigg put
+dup 195 /parenleftBigg put
+dup 196 /arrowdblbt put
+dup 128 /parenleftBigg put
+dup 0 /parenleftbig put
+dup 1 /parenrightbig put
+dup 2 /bracketleftbig put
+dup 3 /bracketrightbig put
+dup 4 /floorleftbig put
+dup 5 /floorrightbig put
+dup 6 /ceilingleftbig put
+dup 7 /ceilingrightbig put
+dup 8 /braceleftbig put
+dup 9 /bracerightbig put
+dup 10 /angbracketleftbig put
+dup 11 /angbracketrightbig put
+dup 12 /vextendsingle put
+dup 13 /vextenddouble put
+dup 14 /slashbig put
+dup 15 /backslashbig put
+dup 16 /parenleftBig put
+dup 17 /parenrightBig put
+dup 18 /parenleftbigg put
+dup 19 /parenrightbigg put
+dup 20 /bracketleftbigg put
+dup 21 /bracketrightbigg put
+dup 22 /floorleftbigg put
+dup 23 /floorrightbigg put
+dup 24 /ceilingleftbigg put
+dup 25 /ceilingrightbigg put
+dup 26 /braceleftbigg put
+dup 27 /bracerightbigg put
+dup 28 /angbracketleftbigg put
+dup 29 /angbracketrightbigg put
+dup 30 /slashbigg put
+dup 31 /backslashbigg put
+dup 32 /parenleftBigg put
+dup 33 /parenrightBigg put
+dup 34 /bracketleftBigg put
+dup 35 /bracketrightBigg put
+dup 36 /floorleftBigg put
+dup 37 /floorrightBigg put
+dup 38 /ceilingleftBigg put
+dup 39 /ceilingrightBigg put
+dup 40 /braceleftBigg put
+dup 41 /bracerightBigg put
+dup 42 /angbracketleftBigg put
+dup 43 /angbracketrightBigg put
+dup 44 /slashBigg put
+dup 45 /backslashBigg put
+dup 46 /slashBig put
+dup 47 /backslashBig put
+dup 48 /parenlefttp put
+dup 49 /parenrighttp put
+dup 50 /bracketlefttp put
+dup 51 /bracketrighttp put
+dup 52 /bracketleftbt put
+dup 53 /bracketrightbt put
+dup 54 /bracketleftex put
+dup 55 /bracketrightex put
+dup 56 /bracelefttp put
+dup 57 /bracerighttp put
+dup 58 /braceleftbt put
+dup 59 /bracerightbt put
+dup 60 /braceleftmid put
+dup 61 /bracerightmid put
+dup 62 /braceex put
+dup 63 /arrowvertex put
+dup 64 /parenleftbt put
+dup 65 /parenrightbt put
+dup 66 /parenleftex put
+dup 67 /parenrightex put
+dup 68 /angbracketleftBig put
+dup 69 /angbracketrightBig put
+dup 70 /unionsqtext put
+dup 71 /unionsqdisplay put
+dup 72 /contintegraltext put
+dup 73 /contintegraldisplay put
+dup 74 /circledottext put
+dup 75 /circledotdisplay put
+dup 76 /circleplustext put
+dup 77 /circleplusdisplay put
+dup 78 /circlemultiplytext put
+dup 79 /circlemultiplydisplay put
+dup 80 /summationtext put
+dup 81 /producttext put
+dup 82 /integraltext put
+dup 83 /uniontext put
+dup 84 /intersectiontext put
+dup 85 /unionmultitext put
+dup 86 /logicalandtext put
+dup 87 /logicalortext put
+dup 88 /summationdisplay put
+dup 89 /productdisplay put
+dup 90 /integraldisplay put
+dup 91 /uniondisplay put
+dup 92 /intersectiondisplay put
+dup 93 /unionmultidisplay put
+dup 94 /logicalanddisplay put
+dup 95 /logicalordisplay put
+dup 96 /coproducttext put
+dup 97 /coproductdisplay put
+dup 98 /hatwide put
+dup 99 /hatwider put
+dup 100 /hatwidest put
+dup 101 /tildewide put
+dup 102 /tildewider put
+dup 103 /tildewidest put
+dup 104 /bracketleftBig put
+dup 105 /bracketrightBig put
+dup 106 /floorleftBig put
+dup 107 /floorrightBig put
+dup 108 /ceilingleftBig put
+dup 109 /ceilingrightBig put
+dup 110 /braceleftBig put
+dup 111 /bracerightBig put
+dup 112 /radicalbig put
+dup 113 /radicalBig put
+dup 114 /radicalbigg put
+dup 115 /radicalBigg put
+dup 116 /radicalbt put
+dup 117 /radicalvertex put
+dup 118 /radicaltp put
+dup 119 /arrowvertexdbl put
+dup 120 /arrowtp put
+dup 121 /arrowbt put
+dup 122 /bracehtipdownleft put
+dup 123 /bracehtipdownright put
+dup 124 /bracehtipupleft put
+dup 125 /bracehtipupright put
+dup 126 /arrowdbltp put
+dup 127 /arrowdblbt put
+dup 159 /radical put
+dup 160 /space put
+readonly def
+/FontBBox{-23 -2958 1456 766}readonly def
+/UniqueID 5018948 def
+currentdict end
+currentfile eexec
+
+80347982AB3942D930E069A70D0D48311D70C1E2528F01045F8CAEC9829F31D648C8D0A29EA8
+51AF41C327A0D569ABAAFE5AFE94DAD818C312D3CEE72F1ACEA0B701B6A5608521A2866790BD
+D5776D6CD0C7D971B9A48B96AA970DCBB8B76EDCB90DA356DC2529B665EB4BB80AC4F5B0F4C0
+ED76861E399638AD3DB1BE4759C78D4F2E81A2FF688D366B91D729D63AB5FC9556FE10A07B81
+904D879A7446DA82DC107FF41B0E3B7C2245D57B2EE9BAB31ECCFE9B79E3EC32CB1F10C622F4
+BCE18DF0E5C4B98EC714593D6F127C5CF6D719A79B83C627433D3AA39CB88EF85D274184C4B4
+C46CA5B496F20460ED75CCFB3D66073B710CC1AD2F2BEC4AC64065ED5E03930ED9EC97810F36
+845DD5048D90D724A88FD3C814CE17C417C84BA45C43F5569A4D73739F71544ED91C657705E1
+31F4D0C61752509FBE0212BDE9C02A833910DFF28F7C53F64B032C8E3CD2BA95C22177C3E053
+2F8699D106F119B80549C45726D793B9AEC38FF4C3120C259083FD13C644DEA026E1E7C75DEA
+2EC2341983AFF4D712C27C024393022797DB1500C6543D620F20C9CE973EF7D917E7FB3E6CFE
+E0999E06C9DFFF2D01BAC5B3BE0C47B2D5ABC02E1F0F383588F430FA64BFD5250E56DA323C91
+F033C8F0F4E0F9CBB36EB8D4D25B127FDA1BB032A7088CF6FB34B617290DE038198297F2AF32
+3602E5E96D475E4678E129D88AA15D5AD9CB58E244028CD8D9A8210FB1AECFC3F29299986C1D
+F1CB3FFA0FC203626E8E2F6F3A6AB198963ACB2B528D6BC06687D59EFDDB9C88535C1C69DA5D
+81812B911C5EF9985179796D2B2E4E92BEEC47A4075E306C8D26431D8E0732768DFF70EF2270
+D1FDDDDD4CCA0F209AD05C9AF2F26DA7CA0ACCC0349D554800072FE70FE3F12F846085405A3E
+13764F457E887846DB5ECA49493FB685ACAC9E0D4C5CA63C7B16408CB7EB5DECB4429557ACBE
+97A89D9360F0D29566678E6C2E3569923451905D8951F729D6E4E166C0150CFADE571C25F928
+20FC6FB202F2D010BDB81E8BAA6232CD15F94AF4804B08CDDBC782C1295ED9D18025F1C453A6
+78F58A7E1B7BCFBA4400DDA52BD25CCAEF380AF4B5003DCC06F75960AC763EC42A6EF95EAF46
+F77B3AA68BBC3C182D192D602A713F8082AF7E531B1282E701D3A39904E4802C94B6DF379CC5
+FAF66B0FBC4E279EBE2154C755887098745EA0303640D9ECD80AD923DEDA40CCA8136F760A6E
+4EAA342751FEF587651A7C6394ED4FE12A07E33FCDC615954AB2599F9A75CCF54E560B978ADD
+203D169AD883C855F40EC67C410BF468E7AD9A8FE58C601BF464797F492CB9354C0A21DEB7E6
+E0B951770086D598FBD0138393A017903AC875192D5DA1D671E70F91C6CD9722D168EEBB3CFF
+B58E56373712AE6823A0B39FE863CE84E8A867C5D1F5611AEFDF25D31C9896DCF5E320B0875D
+D95C3A3F8BA7A6331558180E833AF7C1625D0A0EFD6266B95BA0A2DC769E694D43AB27088F81
+E8A7F25A9207EFD5AB98F0390B28D219AC289FA217FA1E67D801778DA34B6CA048034A044E83
+294061D64A98E7B5989EA55D9E4B046545C841452C7E8F23ED381387E1EA4E2912922C12ECF8
+C2822605C9934C37FDE6571C287AE7D66B15AFCACC0063F3EBD6FC91F5483928FFC85FDC712E
+C46352ED74FD90778B8EA75A41AB0CF6A619FBB4187C77274565241CDACB46D3A96A66DE00BC
+129825D7210A09757E2EAA6F6399E49A2FA7CAC9A2EB475EE8DECC5785DD1AD632A308872F86
+B8789E949DE16E8DC5B9BFF155EBCFBCE24CB82077EA65F147D6D2070BBC33C7B2AFB4A55369
+0CBFCE3FE274EFE7CCDD768B257FABC2EF28CCC3C361799EB6365F41927A1859EC2CE5A07EB9
+FDC066040ABBB17E98C5287CF3DDB94E5EB10375B52239AF35B012882A8F3D338801490D3F3F
+FA3160C62D9E5E82EA6A456005BFA2279CC7E72397B09419D539EF1864ADC733AE203B2D8F72
+15B1A449228AF2666A8E5CE4C03C09E85AFE5B179C139027E0249D75A2EB070463CDCEEC2CBD
+5D113829A137081D755ED274ED76D511C332222FCCFEC4E75FA82960F8D544A384D7A3760675
+E76312EABE9CBDA8B23716F835E358859A7A6468A890A0E5726F161F6D9FC73C83B27325E9E1
+8CC902D1CB601CDC9C66CD1ECE834FA07A0FA67AB883E1A415429E238093EBFEFD0911283CD9
+698B571A023B18E1BF83878518DF8F783E42202CF653BE501F77AB4074A5A2D10C569177DA76
+0FEE25D893676DE5025DF26685782D2EC98BD168DF71B5041F9F1E502513235B3A0198AA12A3
+91F664BCE4148D328685938AD62A83D215FA65AF0A2242FF495C97C08708BE977F3A0F635DA6
+85FA0224E9A3106AFD6606C580DF1EFDAB02F51B8D1409688A2FE0937DC74503D713BD217815
+8C6E89304F691C05DDC18B9501A0EC292B6900DB8DC47AF1D118336C459327E4E9134485AB76
+4D7E150A1204B61FA48D6C64F70704118DDFC63F7FB133FFDE65F278E2C61A5913DFBF4C6C77
+C019A13933B9C84DC671FA376BDBCF684EEBEF270C7C9BE054DD27DA19CB46C8AE6770A8C375
+3F44D645C626E640A1328B864A6038310AC575AA8D563040E7979F5B7128841F208C1DEAB059
+F4A125F72E3F508540C6D2338730B5AC7375E158CF49BAA7A095845ADB6BCCB32ADAF8163BE8
+4FA8B8652FEB9D9E4C3A8660233CD8BCEABBE97F90DABE0D18B04018C129C7A5F5FA0C7D4188
+68904E005BE329EC6A9B977FEF88806F0FFF2F285DFCAEBAA69E1780EE9BFD643EB41E380E16
+B87BDAB8C7622BBE4F26C356929692E3269715482FBA49A1C638A01BC95D764AB297DFE358C5
+0DC4384C443CE04BD2D5CC334870981F4F66F46388415CAE55F3CCCD74B189495505D75F945F
+6F1BD6B7954FDC5A49BF2DDF4A32EA9437E1540BA8389C5197AF1D84091244AB411AC98AA6DE
+D62AF3C2A8D7027A055A23F486A62CB8C9B727ABA8D05638E4CE62735A66AE83DE1191C9D32F
+5BAEC262235F051F6EA5F9AC9618B3DAC8C805085CE8D6C03C94E63C96052C776BAC710C4BD1
+D34587B13356203A8B603F1095A582350E8EE92DC0F17037CC1C7A93ECBFF488AEECECE7AF19
+CA0ADF364C275BFD819067BD6557EC7B726E28111B3F3A137CFEF5F9EEAD77DA5C079A67A0F9
+EAF10656091E274CB52CB8196A3CC157720DA741E833758FF502507191B876D588AEF7E53B98
+1F87015B3A597A93E1B26AD08892956A4055AA05EA2273E84F288B004027DDEAA151BD24F504
+127206FED840BF1634F21A8C0E63BACBFABD1632E951D10912EAC843D2B956F12364C6B03C8E
+0AE65C8FDDCBB882A5D6C99D79BEEA1BF8C76DB4AB6497B532FDE33C2CCFAF6CDD6B04B630F7
+3365E16F9212D3F75C1D655663FA2F9FAE6A872B8F4DFD4FBF357D7B22700A26BFC882A33AB2
+327E92A3070C72DC798687D2F01178971189BDB62A83936E0C0319073B037E96B6D125D401A5
+325725ECA5E701A51B3B6AED5FDCAE2B5B6284F671E855BEF502EED95E9CDFF7184F09754B72
+0292C91383363102EE9D37E6A8033631A0F4C11E197780D23486E647113B222E6547B115A899
+A46FE587AE36FE3C6AA75DD596227975FD55213EDA6DA9AFC0B39BE1D81C4932E4AE224954BE
+F7E8FDB0FF8813F5F8D75E68F06B36F0796CE1E43F5B9D93627B630D2094269493161CADD19C
+075CE39D381277496215F8B64AACB40BF623E2D68767DD05781909A1242156FEF405C0ADA5C3
+6F50ABC723F4BE18CBCCC097DB5FB48E30E18B657D54F4C1154ED50B342B4A00F1A4C0CB45AA
+61F4483B0691DD6D52F310451F68C58DE913DE1FAB27849D9B9AAD9DB3C7C4D25B797306F2C1
+39CC43DCFEED1D0866ECA6F0321E6F49FE12965592F82DDB775EBA4E9C63A484BA1B36E636A8
+420B80D044C3CA74E7D02F3DD99833F979B2BEDB78D9E95B060B4D8EEE1B9CA4D3DA02FAAA9F
+37680338851C6DC9E2DA0C1A17DF83190E9FD53DAEBF360E0777C7282DBCF02CBE01C7183E9B
+BBB66649F3A4E1F30652D7A3D2D718CF9C44978E614025A9EA26A8F10F23EDDC9D7C563C2A9C
+D406563C9202F35E760ABD0BDA1B3B7AAF882094C8524F1D0F5F7EC20FF38BAA21C8D47B1C50
+3EB79C31CD2A8133799EE820F71F04D1F71586D11C369AE5F131100B0D9538FE37786AEC273A
+45223CF10AADE8D0E55F27916C4A6A3DC45F8FB0BFEC06F54DED4FA2F280191002E804E4558D
+F64015EAD87DA779CAA0AD5F30EFF42738901A1E9F067ADBF578755C4CBD14455A7658E468DF
+3C3D37CE976809259716459BB849E94FA803C1D7CC9BB6EE349E12A0E64676161434CA1AF6FB
+72F6F3D28776F147AB78B522B76625C0567E945BCA6A04502B17F5F876E6828F59852F3294D3
+C7F4451A7A561E0CB4F19616E55C01257E2B673DCD05F939FFE995A8821D159324337BB2534C
+1B9B07E1B9132C53AADC91AF43698D52ECAAC6B45AE7813AE95FE9B3C09A6676DB5E248C3CED
+2D34D3162C6B7B121EE0B641473F8264836390FD68787D13EF6754AAD7478C4706D17E9E2FED
+78491084131C407BFAF7281E8C64B65A11FE07EB111372FFA056FCBACA81D412080F53D2D837
+0252A767C4D67FB55D9133D7FCC1256C0258942FC094F1DCF076ACD3DB978C00968B021D802B
+D11DBE9B4C0C0FD89468C05AC183606DA96A56A14C9851317DD75052A86E30B7EC13AD0E6474
+8354F40A5F38DD025F581EE1B813B5BCB4DF38240DFA342A39321DD3AA32D1D206CD5681E3F4
+B5C638C14BDBBA48381D18A4765C04525A43AED29F47BC2F41F09E98F9942462137BDD76EBE8
+AE60C03970CAB12B113B0F15D931F848AC1201DBA25F4E81B7F158E033CF2A4DA3856CF6A74A
+EC130376A132AF3E763826B26BE54117AA646BED395228062EFCDFE78AF46ECF686871A570F2
+B20CC2AD65D09F868189128F7D41AAE20DFBE729870552C0F56F8C4005D9161CA4A5498AE2FB
+F3E1FF9E02C050D3634D0B88A32EB75B3D225633B85085252F5939CEEB540D8B5F60A090B4BD
+F2BFA14E1CB911BF23E7C3DA05BB28AA3BFE0676A3DAAF56CE804D425DDAE061281B248506F3
+88D9F7C4C95E2F0971316BC3E9BC783A30CE88A80BB247B6319721CFF31603EB1D1670F522C1
+46FED5F0B12ACA993397C06BD37FB7D439D003007853719A9FE2FB3B67D27D546FA8F762BA53
+18417F0D2CBA448345CC86A2338300D429A16B3453969EBC5D41BFCCE59F0EB5E443C6C706E2
+ACBDD250F74936E53F443019F97D86536913756995AFF9A5A91D93E093EB18EEB08F88C9F8B3
+354E6EF643E93937C2BE255C876272098538F181E68E686860DA6D6792D1FB2B2E1FE30F0662
+ECEEA87B37C436584B153C615CA7703738F708224C0D6B58BE2C3AE36C0E892A563F68AE1B11
+67C84B6527E34B98AFA281E4D03BB1BF6DD356D31DC794F92384A3BDA7EC3FE9FAA036575951
+0EA74B8937E0E38A04A58C623F0AA1787BC826DAA2364EE4CFA8B01B81EE5DD843DCB4048998
+E0CF8D18B10CA883233DE06779C332D29C87A7EA33F057ADD9F4C29A6970C56E170A80AF2A1F
+56DDE778FC149469C5399F3E2C4EE34E3DDE95EB0CBD2A332B91679AAB4042DFF4CA9F2AB97D
+06973892401B0F45A6E9FB9E7AD6C9B451DDE4072D7B68FA8C54A40276CA033E22783DF35753
+C60AB951A49CDD141DD12330D13CB7A205941D2A9B303BB5AF4A7E14A0FCE57192BFFFDB7414
+F4DC3262BE1E60DE8E4B5BBA84661DEC9B6C570E857F5905AC639E19DD553D57C2FF30F563C9
+1C4CFC74A8B08A961C3892633F988DD2C43BDB34A0F6C1ACA3700C1EAA12EA6FB3424F693A7A
+CDCBA056556D7CD8E7AE6A966896A83E3AA73583A4196615ADA7082E964508EC5B20793A93C1
+ED113A816EB7CF05C2177F127958AAE01E23A3E11D81C4A0718CA2897E1DEB6B911F70A0DDDC
+1EDAFCFCCB9030BF887F859B2B9D471EEE0BA651D858B196A19CF76F3F896649CD0ABE276D3A
+C48EE62636C457F55E7C2621FB81EB168B861FD588FBC53EE99936E31AF2174A93F37C856421
+CF04098EE6E737030C47CEA6465A967D3B15038507DDE2D3AB2ECB82F5601D04CD74E38D8C17
+7CCB0E4209A5F83A5273FD99167B8ABB8DA1B3C661E8280D5A3552E1DFD6A53C6BA68118F6BB
+86FC0205B1DCD030D4C20769A5BA10CDDAC3180CDAEAA8D689051D517B10E505EE47D2E75898
+B66A8B12046EF9DC2857B96B15DF161B7EC0E2A6B32E11DFDAFE47031338CDF0263E80B3EC9F
+488A00C564784C0F5C5C62F6587C6FED0FBEABE0D5AEA15703000D0616E74FD52A80A6BEB318
+D7CBD787F16EB8BA66CB3AFF1D663DF6EFC7B2FD3497A9C5C7B4CA39001C65AC18D5E9F9E0C9
+899D972CE5E6AC875CBEFFEC6E5342A3F213DA1AD0EDB5204F2708327DAE47EFD3BACC26EDCB
+44E553CF419A6CDD855A0661D409B06EBC76C9E5393797E33C5C9A1D3F40F85AADDF78C4D48B
+DEDDBF3852AB90BB2212C9A479547E7137AB49E96AAA1EB6511A25F8A39FF0502AE15FB3B198
+79573F54EA6C822945F4BC9585C23C6A7712830A89ECC8E03001EB382358E186492971698748
+431E65800A19D6099650763E5399800A598D8794B042CBC59F5939716E2F33B5133DF9F60F7E
+5AD538AAC1C67BC4C4888D4A966961BB879A4B1F6461F1868FFC4CC38C67471D7F5228E9511F
+ADDADB25216E255CE86F25C74B682435DC57FEFC0DDF09012D401060356AA17EA9A72FD6E485
+4FB46EC0D4C5BE714979280F4C5472E746489B97D11B97D736F74604F4B61D907FD41DC25736
+CD9A3962245BB7B889613EB3209A064C8DA94260C0BD5D3489DFFAFD3CFC6B897E144DDF5075
+897CC74778692C369324580948CC0536033BDF403E7AD308C79A71FDC89ED669888E9DC7C9E8
+4D094AECFD4136CC3225CACF9EED5BB84BF0B5B865C015010F1D23AB7AA2A9B1AE50801FCA0F
+BB9B37DFDF942F49884F2A1D988FC17A3665C00817272566907DAB9BC3FDD0C457542E91CCEF
+013D2CB09464589552DCB8C0C9C1F9E43BE6238D12F2AD0B0FD5F91CA43BE45C92A6622B36A2
+162CC138AAA8371F75F3EE74290951C3F560662A5BF77E37145593AAB1AE4F5BDA574A176C34
+868F351C39997D7A725137EEA7A46096E0766EA71BA1E5DA00E33440EFA6BAF2346896EBDDEB
+C3C87CCE018920B1D0BEBB660A81EB233EA9923199963FFBC0B30E6AF15704CCBA48CCED2167
+899B66CC3534EE33406F44D8E2C0ABED37E07217DA2F8C4516D98EF10BED1A355E8E8DBD593A
+7724979770DD4E67B977829DB9F89F22AC31D7FF6637E02ED68E377600A438880A19FD377933
+0BEC227FBA1631D1EA18730F5FD88A9E7B66DE04327921A52F52EA62D33F338FDDCA44951983
+5FDB98FC4690EEA8EF5C90A9073352983540CDB356B91DEA0BE868F5EA905B2DB36FEAE31387
+4274442BD6A3C7709EAE9A3637504E1686453D4E7D41B8F6CE63AFE7F8C4F3F70F8BC03D4DA0
+B43A3A61106C6C757996FEE8450BE9D1D4E4B7A302E610F6E9E34762248A42A14F1AB4415387
+4DEE34FC1F0805008D6105BE49F30DE3228E6F56BFB1AA7638E691DDB1F9A5F8B2B70B6F4365
+9CF2133100306C9897131F0604930CB664B922790831C3F50E43D568B9916F47BD4A2F583184
+A86684C8E44C23648A1CAAF49602004907C06E466AB016390233180E7E9D2C1B4353288A7366
+F07A5D60B435068D3E0FB35351FF72A4A06C31E710E820B5874ABFB98CCF6B0FC2F1DC25F353
+00C01E54A07EDD2AFF15194DD710F77BDDA55F7ACE05210362D3D29CE1AA7C338538B2595B52
+3216B6F724F314A5968072C47C0A36198B7A0DA3BF2350281B8A635A83AD7B9F055383E8D675
+3537187EAC6B24F21CB4F840BCA22E1A7417D730C9CCD0A97DB533723253F92A2B00BB5DC945
+2485D1E0B0905DF2C6CAB95C9C4D501E9D45FE306FAB2CD8379669D56EDDB75D0F67E1C05C3B
+47934CAFD125943FDB781C7393B2C426EB609C951A9D1E9222D16527C20C8DE9F6CFA0DEABA6
+9E31F28A7253EC6EC44CF054AF4DF1B7E3C655A91FB8FD88D79ED755B45C39C02A7D73A3F888
+F99AAE2586ED69F775384FB89B695358344BC3110BCEB38867A8CD54E8BA5687A552A30454A4
+4C8D089E67A19A15E65849DB7B39576FBB2CB4074AD8B4ED440CCF3EC2E932AEA4AF06D87997
+A1967737006392D6AF327387556A5CD54A991E5C23D862E9A6BD378E54BBD63FAAA3C18A133E
+B47227C3F87A3F70324E24D7E975873815F6140969942F53D36917C7DC8012509973022CE814
+57FB43989D9F158810C3995C1D24A884853B9D6C250BBD49CDBA3080B3D59BB2F01812D59DD7
+C1823325DF1609A51E4CAD16E75669DC416590B526402DFDC0A966A284E950B96A489DF5EA1F
+C52CC43738ABF53BEEFF55840C3894019C23AC6319F2DAE587BBD9119E64869E087C221E9EA8
+AE59CC5F7945E133F18575D39F00B920BCAE3105332DD77E876A4CE7A71E278F63DEEA7408AB
+B4B110D52981C057B881CD06DD3091A8645231AF350126B7C7CADB6B89D2BCB1F3778F7F9C34
+623C2CB1537923D336DC75F2B3F06FD16DFA756B5C37F7EDCD0999583ABE6FB56FDEA2A64B7E
+D3DFEC1D064166E57B821BDE93CEBEE3F41266927EFE03E646824BA6332B5D2A8B24A469D453
+508DAB6EF30E56FB17467416039E877CA59088FCF3D76682605698D61837448F272A9EEEE609
+E4E44B72B16031480A7ACCE56C042253B2761E8ACFFE13D09BAA39991AC83F7A7BFA671960E4
+BB054C66A544FE3D7CEC4732A77BDB619E0410E61B93BB45463FABAE0E8D44A5CD77E58AB55C
+6E3A9F076AFE892FA9E43BC038380B5D1EB9EEEB5BB5CF0C96E91730BF186AC6D9D337C989F9
+4611C06666627266D0D304524CE7A87907D9C022E23000BAD7AB7743F2FCDA576D745B7D3346
+827966287BB484DA9873C7F491F02401A864ED4836E5920E3AC084B2D47098FBCE36EA223195
+6347B9CFF7942D60315119D3DD428B097AC82E009209A4CED3C5CD3B30F12457022D7E841959
+CAC6AEBC2DFD9287ECC7AC2D5B3A1DA280BD4E1CFAF1D17CE1FE5C3451949A8ECEE3368DF1BD
+A3E5515C5C0F80B6273375BDEC432BDF1B78FE55F92B4B362DBD8C129C949DEB07715C8794D3
+5C3F49107430C4A604CA833093BCE1B95163A0D1345406FF054EB3B54FD5BCDCED531E01D252
+E6DB7162CFEF34AED6453BB7C61B7BD034B46703AE80309B4F5DDF1B15A40088BBA0FC55EB0A
+174B97BB1D934C0BA8E5E6ADC41617CEBE9F18047663C635EC18B9FD1C0FAE76CC9038933BE8
+8C704A95D2F0D67F57FD061CA9757F46DF057D57D5826E2B49FE4454AD2671C7A4AE5F24F83D
+F0A6A878F4F3A00720067DCD7B05E55564DE4D8AAC16A8C30DEF7155855D68DBC9453D5AEA88
+4D332E150A2AD5537E481D74DF2AE87FD227C08993741E9ABD9543D98767B4FF873969BD40CA
+F3D153352A9B3430B46B88A4BEA305D955B277116090A3DFC81F56384E2666CC1F36E102C546
+4D09870A2EEB97FECED0B99C2862943C6DF1877E178141CF7361F74399268F4B77453E0731F4
+BB8DF0011E6328346253E12D881124534C9A64BA85D272A4FDAFB1DA8FF50C4F149D37C251D8
+3B5B4135C805D90F33E1AAD01914156A98A6AC178639D10387460A56D0C0B50E331131BA5522
+AF79ED5347EC80164A111D7C2286C88B851C43E893580DE162FFF77C0887DDEBFC82218434C2
+9B33A86140E4E1C9E46E8B49A83F656F0B46C917F603CD7CDF15CE8B0D49165E569B3BF18BCF
+9BFCEC7DFD8B2010DB8D863C5C5AEDB36C0193392D565C24AD764497AB5331E7DF468ACF96D9
+8707CF755765D22C8876B2F15FF1C4AC403285BC2F21737675153288EDB766C6ED80588A503C
+2291960EACAB24838E0F300C36D0E2050AB6C8D39022DA292FECDE19A62D5D539D3C66DBBAB1
+7AB4E9DDD0F3A4DE5A49D513786FEA2F0DACA2F3D52196FAEEF953F7C20386783323946EB1DB
+BC774740333C5F3E6AB79D59D2C712D7AA90D8E96C5573925879D922E1807DE2039E381D1E6E
+07D373D4C30F09253F4DEB3C8EE7ECDFF7A141F7450D0B63749256D96FFE8D8BE744786B4C28
+A762FD6A6403D8AEA0D4FDE81DF3986C7FCF3AEF0823176E1D7B234E4FD9C97CC3CDF7308E76
+BEFE9F11828AE7038C3C0D6E7ECAC8220FB9D05D99DA6B263A316A552E5070DBDB9582242492
+62706696970665B510F39182A7B79AF809B018353DE9E33FF4A745F777AB78E35BF901BF74E0
+45973BA70C96F2CE2F102AA4B5B5C997DF01FDF12A278247577D70275A2EB629D613898899EE
+B39DFE950A7CB1B9F99F6EDFC378CE0B1490BDCA4F7E5614D369DA821C105D8D52C7FFB12F9A
+B8DC180F59B137BB128BBC6C3764E3B8A44FE7152535D1DDFD152E2B9C2411EA530937F11EE6
+379D027AB5EBDE8BAC03BB9697836D2981749A4634A772063F04C81D54FA0CB61899788562C9
+AE5BBD0E3ACAF3E4607986851F7DC7F46C48B89BDB9A18E25A053BB3E84740760E91D2342225
+6109FB8F64F26F5E1E2EC47A09CF9392FD00FD61B422D597FF9C3FB325D4E8FD6FB892D24E28
+CC2FDEBB9E004D10A5AFB10D4467032075BF0B44DB26FB866E1730A60F87A3FE2E940E982A6E
+4633B744D5E5CA36D6F6BD6714ED3478D64F8CD7F5A764E4EA4EB60639DA4E3B5DD0B6532381
+5820A6C70EF2D53A47B5085F9C74BE5E5E42E8BC5DADD35EBFD9E41C44A3B04651C5D62EA746
+B77182A81207D83D855F981CF2D1A23979D485A93658DBE1C69A003FE86AA64C6E7C382C83DE
+F48927EB05BEC2C78466FBE79CBD59E73FC933485689D410A078C59A70B2B5496D1622AF30E7
+888EA2D3C0706045584AB89BB2A5ECA93A686D7BAD8F2DF0BBEC73F4B011EA252FA4987922E0
+A1E9CB93B9F3AC9273F78233BF8E3C9B9CA538D170E01785846EC6CBA18234C2027659D0252F
+AC7E392C40CA3BAD479B154DDC418708731E1A70446D67F69E73957922114413A1C8921B91C5
+B542C2C646744128FB255A6CB3485F1CF409EF9776F200053BC89A499DACDCBA22613FE30654
+08DDA78A9741D102CD5EC74F7B6E80DE740E45D4A64DD13B70B2DCA6CA65442B12F922119471
+CD610408731735DAB12FF45494BD15D990EA4D6EE33AC20C00BB528C91CB7A5F049B187B9D7C
+502DD7DA643FB5CED04AEB894ACB2CCF3D56D656E0551E5757104BDC29DAFB6C80A10B609494
+1EC1041FABDC2AAF1559E032AAA1B79575C4FA9D4A8917FEF7FA6C349A389E1F0D36D5FCCAF6
+A6CF66ADECE06D92592EE8867F2B142A8FC2FB772DA6C814FC6F6F66373329F2CCF69289085B
+8AD7AA5B88C6F7A19CFA5E37BDC61561A82DDF0939844D8ED64BF11084F32C55E09852C6FA41
+A1D9115D0C68DABA31E4FB77D04E5A2B7EB79B521669C629BC9A7CCF129A2A67C92826A435AF
+47F0243E14F1F976EA5B58DA6D79499332E85BF2DB5A7E95230979B6C567614E6370A9B341A0
+7D7813C42E8A1251D77AC6A59B6F5B6082F249879D2122B19E7E5AC42026B1EFA799BAAFE866
+B4A6DA7444C903FC0B45122857BD20B602883FE1E2705C0A27BAA636D0356A102093CED97308
+1BC38EE530B62CAE35C5847EAC973F02BBB7461895C526AC25674C972C4E61BDD86F4A852E15
+AB6D94403A030F32C8F3263113A2D1413E624A8143EA7A9613A2DED2C243266932359120A083
+673020E4134CE6483987A1C77E140E6FF5DCD2B3ECF571A52D3411CD5DB601EF4147C4F1DBD1
+EB16C4B838CB9A6640D8AD1A526C312E5CC7BD5AAA9442A6B38AC29FBA0994C91FE575840038
+13F9B8FEB92B20AF8B890BEC220BF995E3680AD69833D08B0357B6606FD60EAE95F497FFF1A8
+02BBE1D3BB3BF6905FBBC1F97A20F78A1B106DB9C158ECF1CCD16E55048CFB4C50E40EA9B9E6
+0768D440A4507F3E76123616FF79745C76F9135BC1104A9F98D6B8A9D299C0E8D3C0BA2FF429
+47CF866B5487F10194A1A8E672A330C0B9CC2202636A5360E10E53FAD86A2D3C88DFF64D4840
+681B6F96E9E797C459A07D0812550908F2AC36E684B1DBF3DEC6074B922E091277493485153C
+93ABA41FD097D94F4BBB95581670A1EFF27A0D267B9DF689E2BF6FA657F87B390EF731538E34
+E776DCC1D14F8959A99AF11EB15FC59376BD1A136E6947B9076DCF62AAEFB50C8D6F9E10E090
+FCC17B6D90A0B05726F9BBF4FD92E08E5CF4CE66C426959A9F2E185B6B395B0DD4C80BB283E6
+16E6001DCA44A820C18F62521F1F1117263401E30F84C5974461E6E270B72E50E81CFE305D92
+4D26924E5B7675B52EDED59B87AB5606EE5ED95EDBCCE5DF07A0D41492A366C35DE50A4BF365
+5E6E0F24AA7DE91A16EEC22A9EC0F9667C831759C688928E217DFC6C7E33516D46A225E44A6F
+AF58C72236D9FB9F2C13F05FA5F92AE1DD970420B7887E6DFA6C01D9C95DD674863AD81AF472
+3413C430CC912FD0FCEFF72EE9119C4A496C888C0562548F0792897DAC12479411BD39D5C969
+75B9140107D14C8BE1EAA5C482455352C2C5ED15172B9DAC379BDF76FC2E8F11AE24057F851B
+0F41A7325994B1B20802F0CD520D439770029EB53E5E989E549F3C055CDA4E37F78E01E9D2E6
+A3D2DAA41232F7CFE9B7E74D87F4B75FB38F72D541D5EAC0D64567AFD28D6D3F07A4E649A853
+2288416A5A51242077DE5138F6BCC2EBF7524D43A6445BBAD2C4E934FD7BB827FD564209347A
+C988F9DD9DA8C73A4CBCCACA945CA135FE83DBDFF85E2622728199FC975EB14B425AD1299F3E
+69BA41D466CD8E6E9146C0ADB8E93ABE70D43A06CCB205313FEFF9B0F22F7CE37E0F132B8474
+5708C1BB0CE575D972524FA551F2E9F8A06C0B2312137578553D9D6C98838F06FA690278E7EB
+A4A3344665C7E7F79C7096238D5CD9FBB12BAF120D1A287B831255A457532BE861B5A8D78972
+2AF86F49EE59915E456E27A3283EF8939AF44119DA2F508B0F0E6DF46B124DB8EC8454B048FB
+6D29261E5819785EAEB7740EBAB7049A5641942407861D6B31E06AF206E51F62DBD88057FD58
+A1E41DDC6FAC15D6ABBF4A50ED13A464ADC608BAC45A230955B5E827CC57C2260387CAE9DB47
+D0E35812414D2CDD6C643ADF736AD15E1759BCC714C45CF38CA8E4C617EA8E6453EE4A908267
+8C3F90B8416AB1F4BCB0D0B3E50198F36346F778F7B572FECC635AC8429C17E2CCB4D8424C01
+69FCD29D4F8BD4364AAA30202D285DB593005D826B29F0AC6AB3A226B394E80580B2D7DE2DDA
+C4C34D35668D3EC1B34199FFFD25D8DDAB1EC7CEC39BB76614E4BA8B30E75253B529C27823BE
+8FDBD9C7103414836F2F955B40B174890B625F54C723E728D0AAB99CE7D73C2AC582ACCEDF5B
+0671C07A97D0A9ED3AB5A4B163C83EA4C1C05F4D6DB2609D1E785D42229D59EC182C0C02719D
+4420F72C6A9224B62FEA5C885EAA2D61DB6E56D29EA8C091803A2222B6683577A1867796F2C9
+F5175615F6D5FBF9E620AAFA4E60C20CF733EEE1D51F5696AF482AC4AD11278E56EDDFA7E0AD
+533FF3ECD2D379C573FBF8E16E3CE11D8EF293967D76408C9C8A3B6A884A5DE9B1D4D40F8086
+48A7BDDE93624BDBED92CE790151E0081B9530DB07E8E982353CB80B50D8B63BCA09A6C42A33
+991C1A305F36857BDC4D18C5679D5716C1B82039C9C9E303B79378B012340DE204495D66A06A
+4415980D023C07148785F6A2DCCAF9E86FF0C9835B47524F9A5ACFE9EBC53F7AA3299D595B3E
+A3867D71AE686FF0FC9F194279746358C72B2B5AA73E6E92B41AB468964567CA14DC213338B6
+4079965E53EFB8E7EB5474E32D67916A66B896D5A88DBF605CFB36E2224E748FE4259844E6F8
+A20C1E0FB06F24772E06EC3C0E53075AF7072AFB2BA562A691B8D98418F38E4A7C7CD0CF7F45
+0C15BFFA0A267FAA6CFA0E82D49D1AB398442119493CC2A2E15689C7B01992CB73AD2EA3DC8E
+4939739AFFF6C7F1D715DA77488F2B5E87E1FE3FF2477B5079705DF17BE7C6ECC949F0904C2E
+89DB22A6890AE6B915896C47A74C3ADD1F8FA3FB08CD8C0FE48D380871B84E0E2E418CC81629
+3DA3F3425B19A66C05C24C7B5F2336EB7D3F57EB972EEE70A6CE9D8A8286025B1DA5130B9465
+AB5A097CF05F99F2F5265BF748D9573EA0CEEBC1F2FD5033141264DEDFD7746B65D207FF6CDF
+E8124AFF6593C6443F8411DC9F5039D02324B14AD8EA9B1A361AAA6168BFA7C813C39CD0E6B3
+2EE696F8C67E5D15C273C12415C40C1B0F2736BFA6731FF10391DC0E23983905BF3235100413
+7986EDE64D0C3345417C1186AB1AE9E09A98C116DF8B0715FF2B1E99A2FE5FEE1B89F3468DEB
+AF2DDDA899B9C1ABA9B2A762B5EA826727E30E158877E646D3CBACF83FD7691BD69E39C448FF
+0339101CF7D47622F295A26A884B236B7E9E4BAE6A8DC38A9BEC2E986552DEA9355C1DF792F0
+3DDC318582918C8BAFBCD567638C99398AF9AC3940F3E3A37D5FB6B2129BB3620742B278A0AA
+044C096B674CD2F6CB4526552FDCB51BD1E7832CF1F57D95D92CB43F409EFA47C0DAD18FA479
+F72F8657970287AF54C70B695ED1F157A3D171D7A16C30DF4F9530D8489A9A4720F5749659AF
+864F1FCCF90B870A3EDBEAE4242893C425F5F0189DB04E3738209737979E12214482DE3E42C8
+9D9E2E8413AF5DE8E2BCF48862E35CDBC822B75CE3475799DB6E1C50071A91C9E0B8B2A23B4C
+78F63DBE558CF5F8D026E1150A0A5A56EAC99C7B3BD7201B86ABA3A24845CC22630B2927CBEF
+55CE3931698AA96AC1B7B17D9DA16983B3DC05C428184A0F86C818DDF1AC539BEA71ACAC2FC5
+4FA6B0B63E3B8FA4647B972815677003482A8851BF2DD7757698A85E892753ADCA249E607FD9
+7724FD34D5B978B683B7478A1F7C931DD1696B7049C8E4A949C28C540FADC908674E517CCF69
+FFECA21FA70C6034F2C1DFDAB530A6C0DC6F8F9963147F7F393BE5AEC11F95674712FAC4083E
+4729A74D31B88516C169B62385D34423047A3A5AC7CF4EC1B3C0755498A06EBEEF941844066F
+140F69FB48D6E0CF4FB678196E13A991BE17A8C9681A535EB0E379DB700C3703BC7C948B84FC
+2E983B77AE2E926005FDA1DABC948CFB557EBBA947F0395FC7866685499C22E3812206F16DA4
+0776AFC8AC141FDA9A1E3C06FFABD1F1471E1D7149ECED3A9F318932EE192A85D04C26697381
+F4C9E5B3FA36BC2C071C08D4C2EE9D51BDAA5D91419CC54F6327353825BF4D983307A7371CDC
+9F8736C6A79DE8FC34182262F5D8F58AFC30254DF5E9B6346BCFB6AE5739E9A5257596AB8D60
+FE0B539A5F8CCF794AB021762104EE69FB1305665D2AD8A04D1C872ED9F45803EAB198402647
+FE98E189FCAE485E55A5198745851D39330456DA286731440167C05ED527A3A3592736FD58EF
+A01209F5D5BD52C873E31DBE8913ED626C61D8F759B31A49A0464CC8CCA713CD8C9796C28EF4
+4F6EDCFD2158C8753F04175175DFA7D174F2261B1D531D3DA4B683FCCD094BE75D58C533CDCE
+AB481E9E72650164F34C32689B9E5B3E15FA75451CD0412CBCDCDEE1C55202F63018E2479E12
+66B31DFCD8EB29EAB003CDE8F9B00708871829E9E482F9F84DABF50E04A005758FB6F79A4B04
+BB349944962E38958F188FA33DA2D33032517B33A7BC638567C2C09BE64996495ED9DDCE44B4
+2C015F39FE9DFE6A486C1D3EE47FCC92241A54272966B90F9168136BD5E4B9902247BD370827
+4247EBB014FE046B87477898AD03893824065CC8D7D7E269158CE72321B28597BEC407EB9DA6
+E06F7A5079080273BB51BACFE3C2A233C6A5CC3F7009A981D593911C8074C8497A097D7F368C
+FBEFC87293DACED1B267D8029C9341235FA531E9B9CD99A47BD939067EC1035778E9F90C4BBD
+42C11F99FC4E2DEF0C65DD628717F794FE3AE20508D39A88F300D5FB033223A295507A212F85
+5344571D2A09E4644AEDA2414359CED6977507B64A4ACA4106584CDE9766482E61B8B21E2F9F
+365670308D51E73E805137B7EC6E0CC773B0B71EF2B216A8FD98709723AE86757E29C5C47495
+57C682614C9E6B9BAC63388312C2CC5DFE9A63E7C8E1D30D02D5F787142385DDE69E3EF14C2C
+F7A1C30389ED2C63B1D19C1530150BC1DCEA91AE06280B9D1C0CAF0AB2C48025D164B37A1983
+0DBE39932823E0B9978FF7D401636AC47300F86148290E0DF001B22B62483740CEAAD2A98F82
+54DBA38D848A15B3EE2C80604624E26B5A45127F58BDB3F1E021C8E0BCF4258F33AFBE778AAD
+8390B6E7E82EA8114169E2775AE75EFCB67FC4F104AD327701A3F81807FCFE47C6060061AB35
+DCD77BF335D806B26C45648F5EE0B5AE053389310D80AE22F9EA2EEF1D068EAF4C776C0D3B2C
+70C8D533F6B6C869B2CB9BE1104C638AB9057764353011728C2EF17E19DEB436B0D4FD544DE8
+0C0D5570FE9250FB028FE5C4F12A6353B65F87E28B2DDDCCA0936BD847E3498B0E05E53553E1
+49B0A2DE1E57E4D84FD6516259C91ACED13FB6EA70FFC03362E35146369FC6D2F943C4881A9E
+68FAD45AAE9361B0EA34749817B3F98DAE65BBE2260F5A8B06F6CA003D16416717B7C740732F
+E19663240670C04C558033793F21BDE8107F8655C7365D7C2EB1A6495F5FDE6D185A85A68C09
+4A96303FACEFE684CB75B2AACCEF45AD68C46B817BFDB41553FF360D07DDEBA08F5441E098E4
+E4A70704C4A6A3E07F6E0E28A582F19942FD7F53ECA391F40865EFA5AE9D6EA2359F8EC74C23
+D92585C206FD8AE87264A06DDDCF36720A8026525A84D0D68AC93171EE2E87571567F300D2DE
+3CFB7DF541128107227D4949F4D2E6BC7FCFB1909DAFBCA11414C31F9A9C6DE380CE616B9143
+5C212C7F52F705BD46620EC2CE434BF73760D3F574894CEAE00E82DFDEF94B74E1A54117B4AA
+B523186ED86DB61A8B842E3869BC2BBB3CB0B587E80963CF1C01D385F20F762CBCEECB1F5E12
+B551447AA9B8A8FCFE74E29C3AE2FD8F651553F80C1AD8D32EA25890D1B3D7BC9EE3571ED872
+BFC14AA5E14B1E24572CF6DEE0A37F30CC26AC91E405957E09EC263DDFEB7870CC24962505FD
+B586FE0D2D9148E7DEC517034D87A3D59AB534362BE565A0B0E83C7036D25F912ECFF4C87BCA
+1CCDED9037E2B51F1411455F1767974B52C9C040ED0F340DF403C70BB2AEDE49D0411037F27D
+E9723419734B3B62613A6AD0D7FFB6B4AD60A927E7A0F6D0770734D886D9CFEFB3D38B701DF0
+88A05738AABDF63CBA03E97CC40943CABD85AE31F3AC3F741945067636CB58B705CF2B6EDE2D
+26E721E0DB36F4355F2493E01347869F8452E7CF368B78A163711524FEB83A87F032BE27C9A8
+D0EEFBD78680F8196640D575A360D916E0C3C4BCF0BAF6209CCE3AB17ABBF315BA689BACDB46
+4C8E64F989B3491D8644C937DF9FBD9BDF4A46F377673575215D5951A67DDD00FFC27F4AF099
+B69A0E42B06A1D012D81C03E7A90893F4E7A9E979EA66C1BE4008443AE66D2237D61E1D51981
+D7E98E2BEB93425C27A9C5A2111B4806A9C55DD63E02B8E519E3B4DEFBAFA1D97C0CD09D5548
+89E67A37FE6E7843DB388AD4B211990DCA56CFAE1A1421E137E340DD93A13F82300F3BAC6C14
+801160D7A486E4D6D86612A34C3CDD889D310A4FF1DDFE9E086C93DCDDC7C9C855E57B2FF11E
+EEB1602AB284A3C16C90471E355EEADFE60D7A4605471A2CF73F6E8C618BC3EDB50022194C23
+F6843929A63DDC83166B7804D5692BB462C2D9D536630BA9E7D09607F5F3D234C39EBF4514E4
+A66525D654D3F85CD8671B8FC7EAED36FAEAB0EBE66B435286C4F1BC9A7260A249FA6AA4534D
+905333700E8575207D7CF4572CAF801E341438866624BF5DB014FA1D54E078241BE2796DFD0C
+41A33A665C77302D6789152BEE35AB214762250491A8F6E2E5163DECAB37F324A6B24E4FC60B
+4E8D09A98E8CA001AC6005742C697F2AEBE6DD2D6A315EB1C2130C62F0BA71A7E623979845CA
+61CAFDE6CD3DC0E3862364E0326BB4505BA76C2E1ABA60F605C5CF16FFB22CD2D473B814B6C7
+1F274218E489C1DA40FDDD1275069D5A3FB8898B3D886B235ED23520CD36D888C484FC952F13
+E7A9A184B4892B88236319881EB0375F631D87C49C5881FB5F9BE508B2CF479496AF4B0A7816
+CA21921563296D2537DBA7A6A5E3C2EE64D14FCD53973AB4C8623CD3E0574BB76D50145AAAB9
+C01EE99218BDCA2250AD2773900B3FE46FB429F636F8A03AA3F85B15A65DB103C3DEA7A70ADC
+8367C3F20425F614C09D7EDF1141E4200B22B0F0ABF246C4B1F3FB4534B0AA0193B35C6C9282
+3BD246C28A8FA1FB8CDD16C35E08577D7CB9D54EA4ED905ACBB4068933A0F0D8BE557A8CAC5B
+9974E12FBC08ED8B3046ECB8F02F618E1AB086BCD379433EF63A578B05A4C0046C083808E858
+1B93B2F0ABF4A2A6416617C8C167BFEB25DD348729DF48BD207D8649234B5AD4DB4387B53015
+BC48ED1305D24AF73F02C649427FAF78003B5CE8952199763A7638133EF3D3B0AA5B84E44146
+73963276A76A6B8953A023D3643E4B860C4847978F5995FEB031C904466DAB7219BC833903E9
+90E24467D0797B8780238ED5B1AB05FAC6F2D8168CF727E0E688020D72D68ACA98B62FC686A8
+1AE8B9F9AFBA4DA0CFC118D04A81DE89ABB0FECC2EFAC05B98724E55FB884A83DE2A0543B235
+466CA665ADFB740D962D89F5D9E0A4BAD4FC8301371AEBBBB28AC5B6636C8892B997FDFEA2E1
+3FD233E46F988F95559290A7C61A93EDF933533D804BA77DE5CFF35B4BE7B4DA25E7A5ACFE76
+F9BE34CECB3F02C706CB40E260CCA8EE8F68E005F87608AF65A7296C0B4C2F90A3802B11FE3E
+6663B5A046CA1EEDB52C50A2849B2996525A5176358B3C91286885B67469EED54AD644F4452C
+9175871355ABAD45682F3DE3FA693B76B6F1B71DA5BEBDE7F7B4AD091FCAC8A7029F7EB3DA1E
+88794777B6213A9C78F6218F025F81BCB0A79CACCBA5872485272508B8D9D17995E11E8B02B2
+95EFFEC42C0CD4A8299011A31D6354859E96343334B32D5F7E14A1AAE407077FE249C5182BA3
+39AE08750A3EA81206AC36E3BAD944E4795F2D5BE769245D83C76311BECEF343192A611C940D
+679D1C2E5A9E7CDE3018A11800C6EE7902B628FB365ED37E115F4C96629CA4C7936EC37437C2
+B6F02A7F5AE65C1E88A6F382BBACE20015403ABB85B52FD484684A2C850C907AAB14B8AAA0B6
+0EDF2314B64ED3F1950A058D0D9D8D6AEB6CFDEA33EEAB955A70953B430EB9ED9E553D594297
+FB154F799A5B4A0FD82B067D8F234003B0023643CBC4FB636D3FF6B7F318F9C64DED734ADA11
+8AB8F138CD94C1564E43B92CBADCFA54FF3BFE5B647A5179CC92FABCB3638063DF444F17C18F
+19DB63066D4B2FD7CF2B3DE63D1CF486DE54991B73D27E6DF0B63A54D45946CEB5C4BDCC9515
+E97A435349D7035155A42C280B075B59BC89845C6E294641D8BA2B49629C9DCEC496EFB8C323
+692347122D0BCEB8E793EE381647B5C922BF838A8568C2CBF709DD6EB70D38923AF564F04242
+EEFE46752AA083AD0F19B0A3492F5721A85A377A9C160A604446C2887E3123BF14D0CEDD2CFE
+179C11DC231F9B3F06EC99C1C6D18671DD57204FF482E1E4D93639246EA912D6CD1005E10225
+F8C8DC2F2E540C93D9DB908AA8B1EA4140B152277A8AA3D3452ABD078741B546012FC73FEB4E
+B882AB0C15D125B6B3DEC6E82A4EC1E11C837C28326E27D17879D9F3688DB1F38191426AA4C5
+0C42113E3A7005F92254B7A338E19C4A06CB706D903FC5359D408261F75F9E9C63D9307BB8DF
+8C9F1FEB572D2BB11470CBE05E9C45B7C17D8A34DE703FF63355599448EA18BD15D7E8FDCF6B
+EBBB2A89C27278A64A154E2C777E1502499D9A51C1E9236F70567DE5B748AF1949BED1C5409C
+151F510424C00EBE7AF3A82D9FB8E898900C787ED304D05159B118B52C8826DA36049B70D6A1
+7BB445711402F8D6217A349B134CFF7C9852515EAAA496CCFDBC768970D464542F1076340507
+DC62041D7F32E25BA02EC9D78F737BD0ECFC7E2B725A050214DFEF8FD72EE67C0624A54B2C00
+B15768B0165F006764B85385426915CA8A3D8782DC05C9F516D85E5ECB5C594A4AC4E42365BB
+4477AFC353E5F248142A3D5A22632DEB3DAC54A79CE890C7EF134703CE3B1C1949858B17F18B
+BCB1FF377C562D6281C3C08A053B50CCD07CDB20C8D002CABEB082BBF179B9A081C16C3F7772
+6C44F8A3D5270BB63B34E8CFEFACD347F448ED5E690129D33812DC4BA7853B24735BD23149B9
+9D73654B4A22EAC87D19FDCAEDDD519EC97C6024B22BA98162DB5B0769327AE6B9D6F7ABE791
+3BBE25CB9156492D57F4F32E47661851DC82BDBEF74F3FDB433ABA59D6799F9B5FB956950656
+9FA852949ED182BD50D4DE2FF1BAD9EB9BB4D617A127ABB7070278A2AB2FB5E518C03B0E4E3E
+15D7531C6B929C74AEE4B275D4AFB0000A309C7AEC9A10C9473FDF77A50F9AFB139ED61E0919
+944E72A0ADB6CC74B9609DFC9CD923C3C5C1BFB3546628E26FD5338005FE9389A493A27594B5
+8469454C2E2530C711F3F02951081DD33BF7A3DB773EA7E446912A18D75841C5B1239D752D48
+48FB8AD79B4B79504A41AB82BB6B43F425909C44853A8A3159BB75B7342F3CB7281AFC25FA76
+93B409FF5DCCD59DAA16E5FDEB1DC19CD1D303BD00D2154F0EC08E04B5FC441010349998C2C6
+EFA036734540532E588FA2A3FF65367997896DFC6A4AC97A31CF6434AEAD822890AA62621F8A
+3E93785EA32CFC4EACF582AE356EBFD7134160519F91A50753898F505AE6BC39BF63F3599C07
+9AFCB6812D2D9B159BDC9017152F4A050B08014AC846F970F2DAD485EF15AAF397898584BBEF
+2FCDD970786C41AF8B2D3728D3D4C5053EAA1FFBBB2C85752F4E8C0D6F6BF783ABB49796D75C
+0F95A0DA58239580180B033816608D8B3C2D5D52A3D50A82D88C0EA92FDE25C314B1F7FB5D22
+0439E685975D29750A878EC4332BC74A67CBC345095DEF613CBD058AAD37EAAF7FF039673D4B
+ECCA0E38398CF8B9CA775AF365AD16572FD1899342BB76C248886190C9B7540324CF7AB6E076
+8BA6CE39B012882AD64B08AAD4C1C40BF75FCB05F85C8CDE44C523D42B47B4C906BDF6CF27D0
+6689352A2004728F724FC37601BFE0C7FFEB527E7070F435D0453C0F996055F80B2AF2A36309
+46ECD88DD8E864DE048C09D0BD90C4F970A005FD1AB27DC2F374C4DB8D6E690CA525E313ECE3
+F8F8AB88E50000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+
+
+%%EndFont
+%%BeginProcSet: texps.pro
+TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2
+index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll
+exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics
+exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub
+dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def}
+ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict
+end definefont 3 -1 roll makefont /setfont load]cvx def}def
+/ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def
+/ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def
+end
+%%EndProcSet
+%%BeginProcSet: special.pro
+TeXDict begin /SDict 200 dict N SDict begin /@SpecialDefaults{/hs 612 N
+/vs 792 N /ho 0 N /vo 0 N /hsc 1 N /vsc 1 N /ang 0 N /CLIP 0 N /rwiSeen
+false N /rhiSeen false N /letter{}N /note{}N /a4{}N /legal{}N}B
+/@scaleunit 100 N /@hscale{@scaleunit div /hsc X}B /@vscale{@scaleunit
+div /vsc X}B /@hsize{/hs X /CLIP 1 N}B /@vsize{/vs X /CLIP 1 N}B /@clip{
+/CLIP 2 N}B /@hoffset{/ho X}B /@voffset{/vo X}B /@angle{/ang X}B /@rwi{
+10 div /rwi X /rwiSeen true N}B /@rhi{10 div /rhi X /rhiSeen true N}B
+/@llx{/llx X}B /@lly{/lly X}B /@urx{/urx X}B /@ury{/ury X}B /magscale
+true def end /@MacSetUp{userdict /md known{userdict /md get type
+/dicttype eq{userdict begin md length 10 add md maxlength ge{/md md dup
+length 20 add dict copy def}if end md begin /letter{}N /note{}N /legal{}
+N /od{txpose 1 0 mtx defaultmatrix dtransform S atan/pa X newpath
+clippath mark{transform{itransform moveto}}{transform{itransform lineto}
+}{6 -2 roll transform 6 -2 roll transform 6 -2 roll transform{
+itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll curveto}}{{
+closepath}}pathforall newpath counttomark array astore /gc xdf pop ct 39
+0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack}if}N
+/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 -1
+scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 get
+ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip
+not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub neg 0
+TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{noflips{TR
+pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop 90 rotate 1
+-1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg
+TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr 1 get neg
+sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr 2 get ppr
+0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 -1 roll add
+2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S TR}if}N /cp
+{pop pop showpage pm restore}N end}if}if}N /normalscale{Resolution 72
+div VResolution 72 div neg scale magscale{DVImag dup scale}if 0 setgray}
+N /psfts{S 65781.76 div N}N /startTexFig{/psf$SavedState save N userdict
+maxlength dict begin /magscale true def normalscale currentpoint TR
+/psf$ury psfts /psf$urx psfts /psf$lly psfts /psf$llx psfts /psf$y psfts
+/psf$x psfts currentpoint /psf$cy X /psf$cx X /psf$sx psf$x psf$urx
+psf$llx sub div N /psf$sy psf$y psf$ury psf$lly sub div N psf$sx psf$sy
+scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub TR
+/showpage{}N /erasepage{}N /copypage{}N /p 3 def @MacSetUp}N /doclip{
+psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2
+roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath
+moveto}N /endTexFig{end psf$SavedState restore}N /@beginspecial{SDict
+begin /SpecialSave save N gsave normalscale currentpoint TR
+@SpecialDefaults count /ocount X /dcount countdictstack N}N /@setspecial
+{CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto
+closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx
+sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR
+}{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse
+CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury
+lineto closepath clip}if /showpage{}N /erasepage{}N /copypage{}N newpath
+}N /@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{
+end}repeat grestore SpecialSave restore end}N /@defspecial{SDict begin}
+N /@fedspecial{end}B /li{lineto}B /rl{rlineto}B /rc{rcurveto}B /np{
+/SaveX currentpoint /SaveY X N 1 setlinecap newpath}N /st{stroke SaveX
+SaveY moveto}N /fil{fill SaveX SaveY moveto}N /ellipse{/endangle X
+/startangle X /yrad X /xrad X /savematrix matrix currentmatrix N TR xrad
+yrad scale 0 0 1 startangle endangle arc savematrix setmatrix}N end
+%%EndProcSet
+TeXDict begin @defspecial
+
+ TeXDict begin /box{newpath 2 copy moveto 3 copy pop exch lineto 4
+copy pop pop lineto 4 copy exch pop exch pop lineto closepath } bind
+def /min{ 2 copy gt { exch } if pop } bind def/max{ 2 copy lt { exch
+} if pop } bind def/roundedbox{/radius exch store 3 2 roll 2 copy min
+radius sub /miny exch store max radius add /maxy exch store 2 copy
+min radius sub /minx exch store max radius add /maxx exch store newpath
+minx radius add miny moveto maxx miny maxx maxy radius arcto maxx maxy
+minx maxy radius arcto minx maxy minx miny radius arcto minx miny maxx
+miny radius arcto 16 {pop} repeat closepath }bind def /rectcartouche{box
+gsave .95 setgray fill grestore 1 setlinewidth stroke }bind def /cartouche{roundedbox
+gsave .95 setgray fill grestore 1 setlinewidth stroke }bind def end
+ 
+@fedspecial end TeXDict begin
+40258431 52099146 1000 600 600 (manual.dvi) @start /Fa
+157[25 98[{}1 50.000001 /Times-Italic rf /Fb 256[{}0
+50.000001 /RMTMI rf /Fc 167[117 88[{}1 83.333337 /MTEX
+rf /Fd 144[50 50 10[50 99[{TeXBase1Encoding ReEncodeFont}3
+83.333337 /Courier-Oblique rf /Fe 205[40 1[17 48[{}2
+63.333383 /MTSYN rf /Ff 144[32 32 2[28 7[28 32 11[39
+86[{}6 63.333383 /Times-Italic rf /Fg 137[31 118[{}1
+63.333383 /RMTMI rf /Fh 139[19 34 23 1[38 2[57 1[34 2[38
+38 19 38 1[34 38 38 44[38 38 38 38 2[19 46[{
+ TeXBase1Encoding ReEncodeFont }18 83.333337 /Helvetica-Narrow-Oblique
+rf /Fi 4 40 df[<3FFF80000000000000000000000000000000000000007FFFFFE00000
+00000000000000000000000000000000FFFFFFFF80000000000000000000000000000000
+0000FFFFFFFFFC0000000000000000000000000000000000FFFFFFFFFFE0000000000000
+000000000000000000007FFFFFFFFFFE000000000000000000000000000000003FFFFFFF
+FFFFE00000000000000000000000000000000000FFFFFFFFFC0000000000000000000000
+000000000000003FFFFFFF80000000000000000000000000000000000000FFFFFFF00000
+0000000000000000000000000000000007FFFFFE00000000000000000000000000000000
+0000003FFFFFC000000000000000000000000000000000000003FFFFF000000000000000
+0000000000000000000000003FFFFE0000000000000000000000000000000000000007FF
+FF8000000000000000000000000000000000000000FFFFE0000000000000000000000000
+000000000000001FFFF80000000000000000000000000000000000000003FFFE00000000
+00000000000000000000000000000000FFFF800000000000000000000000000000000000
+00001FFFE00000000000000000000000000000000000000007FFF8000000000000000000
+0000000000000000000001FFFE00000000000000000000000000000000000000007FFF80
+000000000000000000000000000000000000001FFFE00000000000000000000000000000
+000000000007FFF00000000000000000000000000000000000000001FFFC000000000000
+00000000000000000000000000007FFE0000000000000000000000000000000000000000
+1FFF800000000000000000000000000000000000000007FFE00000000000000000000000
+000000000000000001FFF00000000000000000000000000000000000000000FFF8000000
+00000000000000000000000000000000003FFE0000000000000000000000000000000000
+0000001FFF000000000000000000000000000000000000000007FFC00000000000000000
+000000000000000000000001FFE00000000000000000000000000000000000000000FFF0
+00000000000000000000000000000000000000007FFC0000000000000000000000000000
+0000000000001FFE00000000000000000000000000000000000000000FFF000000000000
+000000000000000000000000000003FF8000000000000000000000000000000000000000
+01FFC00000000000000000000000000000000000000000FFF00000000000000000000000
+0000000000000000003FF800000000000000000000000000000000000000001FFC000000
+00000000000000000000000000000000000FFE0000000000000000000000000000000000
+00000007FF000000000000000000000000000000000000000003FF800000000000000000
+000000000000000000000000FFC000000000000000000000000000000000000000007FE0
+00000000000000000000000000000000000000003FF00000000000000000000000000000
+0000000000001FF800000000000000000000000000000000000000000FFC000000000000
+000000000000000000000000000007FE0000000000000000000000000000000000000000
+03FF000000000000000000000000000000000000000001FF800000000000000000000000
+000000000000000000FFC000000000000000000000000000000000000000007FE0000000
+00000000000000000000000000000000003FE00000000000000000000000000000000000
+0000001FF000000000000000000000000000000000000000000FF8000000000000000000
+000000000000000000000007FC000000000000000000000000000000000000000003FE00
+0000000000000000000000000000000000000003FF000000000000000000000000000000
+000000000001FF000000000000000000000000000000000000000000FF80000000000000
+00000000000000000000000000007FC00000000000000000000000000000000000000000
+3FE000000000000000000000000000000000000000001FE0000000000000000000000000
+00000000000000001FF000000000000000000000000000000000000000000FF800000000
+0000000000000000000000000000000007FC000000000000000000000000000000000000
+000003FC000000000000000000000000000000000000000003FE00000000000000000000
+0000000000000000000001FF000000000000000000000000000000000000000000FF0000
+000000000000000000000000000000000000007F80000000000000000000000000000000
+00000000007FC000000000000000000000000000000000000000003FC000000000000000
+000000000000000000000000001FE000000000000000000000000000000000000000001F
+F000000000000000000000000000000000000000000FF000000000000000000000000000
+0000000000000007F8000000000000000000000000000000000000000007F80000000000
+00000000000000000000000000000003FC00000000000000000000000000000000000000
+0003FE000000000000000000000000000000000000000001FE0000000000000000000000
+00000000000000000000FF000000000000000000000000000000000000000000FF000000
+0000000000000000000000000000000000007F8000000000000000000000000000000000
+000000007F8000000000000000000000000000000000000000003FC00000000000000000
+0000000000000000000000003FC000000000000000000000000000000000000000001FE0
+00000000000000000000000000000000000000001FE00000000000000000000000000000
+0000000000000FF000000000000000000000000000000000000000000FF0000000000000
+000000000000000000000000000007F80000000000000000000000000000000000000000
+07F8000000000000000000000000000000000000000003FC000000000000000000000000
+000000000000000003FC000000000000000000000000000000000000000001FE00000000
+0000000000000000000000000000000001FE000000000000000000000000000000000000
+000000FF000000000000000000000000000000000000000000FF00000000000000000000
+00000000000000000000007F0000000000000000000000000000000000000000007F8000
+000000000000000000000000000000000000007F80000000000000000000000000000000
+00000000003FC000000000000000000000000000000000000000003FC000000000000000
+000000000000000000000000001FC000000000000000000000000000000000000000001F
+E000000000000000000000000000000000000000001FE000000000000000000000000000
+000000000000000FE000000000000000000000000000000000000000000FF00000000000
+0000000000000000000000000000000FF000000000000000000000000000000000000000
+0007F0000000000000000000000000000000000000000007F80000000000000000000000
+00000000000000000007F8000000000000000000000000000000000000000003F8000000
+000000000000000000000000000000000003FC0000000000000000000000000000000000
+00000003FC000000000000000000000000000000000000000001FC000000000000000000
+000000000000000000000001FE000000000000000000000000000000000000000001FE00
+0000000000000000000000000000000000000000FE000000000000000000000000000000
+000000000000FE000000000000000000000000000000000000000000FF00000000000000
+0000000000000000000000000000FF000000000000000000000000000000000000000000
+7F0000000000000000000000000000000000000000007F00000000000000000000000000
+00000000000000007F8000000000000000000000000000000000000000007F8000000000
+000000000000000000000000000000003F80000000000000000000000000000000000000
+00003F8000000000000000000000000000000000000000003FC000000000000000000000
+000000000000000000003FC000000000000000000000000000000000000000001FC00000
+0000000000000000000000000000000000001FC000000000000000000000000000000000
+000000001FC000000000000000000000000000000000000000001FE00000000000000000
+0000000000000000000000001FE000000000000000000000000000000000000000000FE0
+00000000000000000000000000000000000000000FE00000000000000000000000000000
+0000000000000FE000000000000000000000000000000000000000000FE0000000000000
+00000000000000000000000000000FE00000000000000000000000000000000000000000
+0FF000000000000000000000000000000000000000000FF0000000000000000000000000
+000000000000000007F0000000000000000000000000000000000000000007F000000000
+0000000000000000000000000000000007F0000000000000000000000000000000000000
+000007F0000000000000000000000000000000000000000007F000000000000000000000
+0000000000000000000007F0000000000000000000000000000000000000000007F00000
+00000000000000000000000000000000000007F800000000000000000000000000000000
+0000000007F8000000000000000000000000000000000000000003F80000000000000000
+00000000000000000000000003F8000000000000000000000000000000000000000003F8
+000000000000000000000000000000000000000003F80000000000000000000000000000
+00000000000003F8000000000000000000000000000000000000000003F8000000000000
+000000000000000000000000000003F80000000000000000000000000000000000000000
+03F8000000000000000000000000000000000000000003F8000000000000000000000000
+000000000000000003F8000000000000000000000000000000000000000003F800000000
+0000000000000000000000000000000003F8000000000000000000000000000000000000
+000003F8000000000000000000000000000000000000000003F800000000000000000000
+0000000000000000000001F0000000000000000000000000000000000000000000F0>
+173 173 294 134 332 36 D[<000000000000000000000000000000000000000000F000
+0000000000000000000000000000000000000001F0000000000000000000000000000000
+000000000003F8000000000000000000000000000000000000000003F800000000000000
+0000000000000000000000000003F8000000000000000000000000000000000000000003
+F8000000000000000000000000000000000000000003F800000000000000000000000000
+0000000000000003F8000000000000000000000000000000000000000003F80000000000
+00000000000000000000000000000003F800000000000000000000000000000000000000
+0003F8000000000000000000000000000000000000000003F80000000000000000000000
+00000000000000000003F8000000000000000000000000000000000000000003F8000000
+000000000000000000000000000000000003F80000000000000000000000000000000000
+00000003F8000000000000000000000000000000000000000007F8000000000000000000
+000000000000000000000007F8000000000000000000000000000000000000000007F000
+0000000000000000000000000000000000000007F0000000000000000000000000000000
+000000000007F0000000000000000000000000000000000000000007F000000000000000
+0000000000000000000000000007F0000000000000000000000000000000000000000007
+F0000000000000000000000000000000000000000007F000000000000000000000000000
+000000000000000FF000000000000000000000000000000000000000000FF00000000000
+0000000000000000000000000000000FE000000000000000000000000000000000000000
+000FE000000000000000000000000000000000000000000FE00000000000000000000000
+0000000000000000000FE000000000000000000000000000000000000000000FE0000000
+00000000000000000000000000000000001FE00000000000000000000000000000000000
+0000001FE000000000000000000000000000000000000000001FC0000000000000000000
+00000000000000000000001FC000000000000000000000000000000000000000001FC000
+000000000000000000000000000000000000003FC0000000000000000000000000000000
+00000000003FC000000000000000000000000000000000000000003F8000000000000000
+000000000000000000000000003F8000000000000000000000000000000000000000007F
+8000000000000000000000000000000000000000007F8000000000000000000000000000
+000000000000007F0000000000000000000000000000000000000000007F000000000000
+000000000000000000000000000000FF0000000000000000000000000000000000000000
+00FF000000000000000000000000000000000000000000FE000000000000000000000000
+000000000000000000FE000000000000000000000000000000000000000001FE00000000
+0000000000000000000000000000000001FE000000000000000000000000000000000000
+000001FC000000000000000000000000000000000000000003FC00000000000000000000
+0000000000000000000003FC000000000000000000000000000000000000000003F80000
+00000000000000000000000000000000000007F800000000000000000000000000000000
+0000000007F8000000000000000000000000000000000000000007F00000000000000000
+0000000000000000000000000FF000000000000000000000000000000000000000000FF0
+00000000000000000000000000000000000000000FE00000000000000000000000000000
+0000000000001FE000000000000000000000000000000000000000001FE0000000000000
+00000000000000000000000000001FC00000000000000000000000000000000000000000
+3FC000000000000000000000000000000000000000003FC0000000000000000000000000
+00000000000000007F8000000000000000000000000000000000000000007F8000000000
+000000000000000000000000000000007F00000000000000000000000000000000000000
+0000FF000000000000000000000000000000000000000000FF0000000000000000000000
+00000000000000000001FE000000000000000000000000000000000000000001FE000000
+000000000000000000000000000000000003FC0000000000000000000000000000000000
+00000003FC000000000000000000000000000000000000000007F8000000000000000000
+000000000000000000000007F800000000000000000000000000000000000000000FF000
+000000000000000000000000000000000000000FF0000000000000000000000000000000
+00000000001FE000000000000000000000000000000000000000001FE000000000000000
+000000000000000000000000003FC000000000000000000000000000000000000000003F
+C000000000000000000000000000000000000000007F8000000000000000000000000000
+000000000000007F800000000000000000000000000000000000000000FF000000000000
+000000000000000000000000000000FF0000000000000000000000000000000000000000
+01FE000000000000000000000000000000000000000003FE000000000000000000000000
+000000000000000003FC000000000000000000000000000000000000000007F800000000
+0000000000000000000000000000000007F8000000000000000000000000000000000000
+00000FF000000000000000000000000000000000000000001FF000000000000000000000
+000000000000000000001FE000000000000000000000000000000000000000003FC00000
+0000000000000000000000000000000000007FC000000000000000000000000000000000
+000000007F800000000000000000000000000000000000000000FF000000000000000000
+000000000000000000000001FF000000000000000000000000000000000000000003FE00
+0000000000000000000000000000000000000003FC000000000000000000000000000000
+000000000007FC00000000000000000000000000000000000000000FF800000000000000
+000000000000000000000000001FF000000000000000000000000000000000000000001F
+E000000000000000000000000000000000000000003FE000000000000000000000000000
+000000000000007FC00000000000000000000000000000000000000000FF800000000000
+000000000000000000000000000001FF0000000000000000000000000000000000000000
+03FF000000000000000000000000000000000000000003FE000000000000000000000000
+000000000000000007FC00000000000000000000000000000000000000000FF800000000
+000000000000000000000000000000001FF0000000000000000000000000000000000000
+00003FE000000000000000000000000000000000000000007FE000000000000000000000
+00000000000000000000FFC00000000000000000000000000000000000000001FF800000
+000000000000000000000000000000000003FF0000000000000000000000000000000000
+00000007FE00000000000000000000000000000000000000000FFC000000000000000000
+00000000000000000000001FF800000000000000000000000000000000000000003FF000
+000000000000000000000000000000000000007FE0000000000000000000000000000000
+0000000000FFC00000000000000000000000000000000000000003FF8000000000000000
+00000000000000000000000007FF00000000000000000000000000000000000000000FFE
+00000000000000000000000000000000000000001FFC0000000000000000000000000000
+0000000000003FF80000000000000000000000000000000000000000FFF0000000000000
+0000000000000000000000000001FFC00000000000000000000000000000000000000003
+FF80000000000000000000000000000000000000000FFF00000000000000000000000000
+000000000000001FFE00000000000000000000000000000000000000007FFC0000000000
+000000000000000000000000000000FFF000000000000000000000000000000000000000
+01FFE00000000000000000000000000000000000000007FFC00000000000000000000000
+00000000000000001FFF00000000000000000000000000000000000000003FFE00000000
+00000000000000000000000000000000FFF8000000000000000000000000000000000000
+0001FFF00000000000000000000000000000000000000007FFE000000000000000000000
+0000000000000000001FFF80000000000000000000000000000000000000007FFE000000
+0000000000000000000000000000000001FFFC0000000000000000000000000000000000
+000007FFF0000000000000000000000000000000000000001FFFE0000000000000000000
+000000000000000000007FFF8000000000000000000000000000000000000001FFFE0000
+000000000000000000000000000000000007FFF800000000000000000000000000000000
+0000001FFFE000000000000000000000000000000000000000FFFF800000000000000000
+0000000000000000000003FFFE000000000000000000000000000000000000001FFFF800
+000000000000000000000000000000000000FFFFE0000000000000000000000000000000
+00000007FFFF800000000000000000000000000000000000003FFFFE0000000000000000
+0000000000000000000003FFFFF00000000000000000000000000000000000003FFFFFC0
+000000000000000000000000000000000007FFFFFE000000000000000000000000000000
+000000FFFFFFF000000000000000000000000000000000003FFFFFFF8000000000000000
+000000000000000000FFFFFFFFFC0000000000000000000000000000003FFFFFFFFFFFE0
+0000000000000000000000000000007FFFFFFFFFFE000000000000000000000000000000
+00FFFFFFFFFFE000000000000000000000000000000000FFFFFFFFFC0000000000000000
+000000000000000000FFFFFFFF8000000000000000000000000000000000007FFFFFE000
+00000000000000000000000000000000003FFF8000000000000000000000000000000000
+000000>173 173 294 300 332 I[<3C0000000000000000000000000000000000000000
+007C000000000000000000000000000000000000000000FE000000000000000000000000
+000000000000000000FE000000000000000000000000000000000000000000FE00000000
+0000000000000000000000000000000000FE000000000000000000000000000000000000
+000000FE000000000000000000000000000000000000000000FE00000000000000000000
+0000000000000000000000FE000000000000000000000000000000000000000000FE0000
+00000000000000000000000000000000000000FE00000000000000000000000000000000
+0000000000FE000000000000000000000000000000000000000000FE0000000000000000
+00000000000000000000000000FE000000000000000000000000000000000000000000FE
+000000000000000000000000000000000000000000FF0000000000000000000000000000
+00000000000000FF0000000000000000000000000000000000000000007F000000000000
+0000000000000000000000000000007F0000000000000000000000000000000000000000
+007F0000000000000000000000000000000000000000007F000000000000000000000000
+0000000000000000007F0000000000000000000000000000000000000000007F00000000
+00000000000000000000000000000000007F000000000000000000000000000000000000
+0000007F0000000000000000000000000000000000000000007F80000000000000000000
+00000000000000000000007F8000000000000000000000000000000000000000003F8000
+000000000000000000000000000000000000003F80000000000000000000000000000000
+00000000003F8000000000000000000000000000000000000000003F8000000000000000
+000000000000000000000000003FC000000000000000000000000000000000000000003F
+C000000000000000000000000000000000000000001FC000000000000000000000000000
+000000000000001FC000000000000000000000000000000000000000001FC00000000000
+0000000000000000000000000000001FE000000000000000000000000000000000000000
+001FE000000000000000000000000000000000000000000FE00000000000000000000000
+0000000000000000000FE000000000000000000000000000000000000000000FE0000000
+00000000000000000000000000000000000FF00000000000000000000000000000000000
+0000000FF0000000000000000000000000000000000000000007F0000000000000000000
+000000000000000000000007F0000000000000000000000000000000000000000007F800
+0000000000000000000000000000000000000007F8000000000000000000000000000000
+000000000003F8000000000000000000000000000000000000000003FC00000000000000
+0000000000000000000000000003FC000000000000000000000000000000000000000001
+FC000000000000000000000000000000000000000001FC00000000000000000000000000
+0000000000000001FE000000000000000000000000000000000000000001FE0000000000
+00000000000000000000000000000000FE00000000000000000000000000000000000000
+0000FF000000000000000000000000000000000000000000FF0000000000000000000000
+000000000000000000007F0000000000000000000000000000000000000000007F800000
+0000000000000000000000000000000000007F8000000000000000000000000000000000
+000000003FC000000000000000000000000000000000000000003FC00000000000000000
+0000000000000000000000001FC000000000000000000000000000000000000000001FE0
+00000000000000000000000000000000000000001FE00000000000000000000000000000
+0000000000000FF000000000000000000000000000000000000000000FF0000000000000
+000000000000000000000000000007F00000000000000000000000000000000000000000
+07F8000000000000000000000000000000000000000007F8000000000000000000000000
+000000000000000003FC000000000000000000000000000000000000000003FC00000000
+0000000000000000000000000000000001FE000000000000000000000000000000000000
+000001FE000000000000000000000000000000000000000000FF00000000000000000000
+0000000000000000000000FF0000000000000000000000000000000000000000007F8000
+000000000000000000000000000000000000007F80000000000000000000000000000000
+00000000003FC000000000000000000000000000000000000000003FC000000000000000
+000000000000000000000000001FE000000000000000000000000000000000000000001F
+E000000000000000000000000000000000000000000FF000000000000000000000000000
+000000000000000FF0000000000000000000000000000000000000000007F80000000000
+00000000000000000000000000000007F800000000000000000000000000000000000000
+0003FC000000000000000000000000000000000000000003FE0000000000000000000000
+00000000000000000001FE000000000000000000000000000000000000000000FF000000
+000000000000000000000000000000000000FF0000000000000000000000000000000000
+000000007F8000000000000000000000000000000000000000007FC00000000000000000
+0000000000000000000000003FC000000000000000000000000000000000000000001FE0
+00000000000000000000000000000000000000001FF00000000000000000000000000000
+0000000000000FF0000000000000000000000000000000000000000007F8000000000000
+000000000000000000000000000007FC0000000000000000000000000000000000000000
+03FE000000000000000000000000000000000000000001FE000000000000000000000000
+000000000000000001FF000000000000000000000000000000000000000000FF80000000
+00000000000000000000000000000000007FC00000000000000000000000000000000000
+0000003FC000000000000000000000000000000000000000003FE0000000000000000000
+00000000000000000000001FF000000000000000000000000000000000000000000FF800
+0000000000000000000000000000000000000007FC000000000000000000000000000000
+000000000007FE000000000000000000000000000000000000000003FE00000000000000
+0000000000000000000000000001FF000000000000000000000000000000000000000000
+FF8000000000000000000000000000000000000000007FC0000000000000000000000000
+00000000000000003FE000000000000000000000000000000000000000003FF000000000
+000000000000000000000000000000001FF8000000000000000000000000000000000000
+00000FFC000000000000000000000000000000000000000007FE00000000000000000000
+0000000000000000000003FF000000000000000000000000000000000000000001FF8000
+00000000000000000000000000000000000000FFC0000000000000000000000000000000
+00000000007FE000000000000000000000000000000000000000003FF000000000000000
+000000000000000000000000001FF800000000000000000000000000000000000000000F
+FE000000000000000000000000000000000000000007FF00000000000000000000000000
+0000000000000003FF800000000000000000000000000000000000000001FFC000000000
+00000000000000000000000000000000FFE0000000000000000000000000000000000000
+00007FF800000000000000000000000000000000000000001FFC00000000000000000000
+000000000000000000000FFE000000000000000000000000000000000000000007FF0000
+00000000000000000000000000000000000003FFC0000000000000000000000000000000
+0000000001FFE000000000000000000000000000000000000000007FF800000000000000
+000000000000000000000000003FFC00000000000000000000000000000000000000001F
+FF00000000000000000000000000000000000000000FFF80000000000000000000000000
+0000000000000003FFE00000000000000000000000000000000000000001FFF000000000
+000000000000000000000000000000007FFC000000000000000000000000000000000000
+00003FFE00000000000000000000000000000000000000000FFF80000000000000000000
+0000000000000000000007FFE00000000000000000000000000000000000000001FFF800
+00000000000000000000000000000000000000FFFE000000000000000000000000000000
+00000000003FFF80000000000000000000000000000000000000001FFFE0000000000000
+0000000000000000000000000007FFF80000000000000000000000000000000000000001
+FFFE00000000000000000000000000000000000000007FFF800000000000000000000000
+00000000000000001FFFE00000000000000000000000000000000000000007FFFC000000
+0000000000000000000000000000000001FFFF0000000000000000000000000000000000
+0000007FFFE0000000000000000000000000000000000000001FFFFC0000000000000000
+000000000000000000000007FFFF8000000000000000000000000000000000000001FFFF
+F0000000000000000000000000000000000000003FFFFF00000000000000000000000000
+0000000000000FFFFFF000000000000000000000000000000000000001FFFFFF00000000
+0000000000000000000000000000003FFFFFF80000000000000000000000000000000000
+0007FFFFFFF0000000000000000000000000000000000000FFFFFFFFF800000000000000
+000000000000000000001FFFFFFFFFFFF000000000000000000000000000000001FFFFFF
+FFFFF0000000000000000000000000000000001FFFFFFFFFF80000000000000000000000
+000000000001FFFFFFFFF800000000000000000000000000000000000FFFFFFFF8000000
+0000000000000000000000000000001FFFFFF00000000000000000000000000000000000
+00000FFFF0>173 173 128 300 332 I[<00000000000000000000000000000000000000
+0FFFF00000000000000000000000000000000000001FFFFFF00000000000000000000000
+0000000000000FFFFFFFF80000000000000000000000000000000001FFFFFFFFF8000000
+000000000000000000000000001FFFFFFFFFF800000000000000000000000000000001FF
+FFFFFFFFF00000000000000000000000000000001FFFFFFFFFFFF0000000000000000000
+000000000000FFFFFFFFF80000000000000000000000000000000007FFFFFFF000000000
+000000000000000000000000003FFFFFF8000000000000000000000000000000000001FF
+FFFF0000000000000000000000000000000000000FFFFFF0000000000000000000000000
+0000000000003FFFFF00000000000000000000000000000000000001FFFFF00000000000
+0000000000000000000000000007FFFF800000000000000000000000000000000000001F
+FFFC000000000000000000000000000000000000007FFFE0000000000000000000000000
+00000000000001FFFF0000000000000000000000000000000000000007FFFC0000000000
+00000000000000000000000000001FFFE000000000000000000000000000000000000000
+7FFF8000000000000000000000000000000000000001FFFE000000000000000000000000
+0000000000000007FFF8000000000000000000000000000000000000001FFFE000000000
+0000000000000000000000000000003FFF80000000000000000000000000000000000000
+00FFFE0000000000000000000000000000000000000001FFF80000000000000000000000
+000000000000000007FFE0000000000000000000000000000000000000000FFF80000000
+000000000000000000000000000000003FFE000000000000000000000000000000000000
+00007FFC0000000000000000000000000000000000000001FFF000000000000000000000
+00000000000000000003FFE0000000000000000000000000000000000000000FFF800000
+00000000000000000000000000000000001FFF0000000000000000000000000000000000
+0000003FFC00000000000000000000000000000000000000007FF8000000000000000000
+0000000000000000000001FFE00000000000000000000000000000000000000003FFC000
+00000000000000000000000000000000000007FF00000000000000000000000000000000
+000000000FFE00000000000000000000000000000000000000001FFC0000000000000000
+0000000000000000000000007FF80000000000000000000000000000000000000000FFE0
+0000000000000000000000000000000000000001FFC00000000000000000000000000000
+000000000003FF800000000000000000000000000000000000000007FF00000000000000
+000000000000000000000000000FFE00000000000000000000000000000000000000001F
+F800000000000000000000000000000000000000003FF000000000000000000000000000
+000000000000007FE00000000000000000000000000000000000000000FFC00000000000
+000000000000000000000000000001FF8000000000000000000000000000000000000000
+03FF000000000000000000000000000000000000000007FE000000000000000000000000
+00000000000000000FFC00000000000000000000000000000000000000001FF800000000
+000000000000000000000000000000003FF0000000000000000000000000000000000000
+00003FE000000000000000000000000000000000000000007FC000000000000000000000
+00000000000000000000FF800000000000000000000000000000000000000001FF000000
+000000000000000000000000000000000003FE0000000000000000000000000000000000
+00000007FE000000000000000000000000000000000000000007FC000000000000000000
+00000000000000000000000FF800000000000000000000000000000000000000001FF000
+000000000000000000000000000000000000003FE0000000000000000000000000000000
+00000000003FC000000000000000000000000000000000000000007FC000000000000000
+00000000000000000000000000FF800000000000000000000000000000000000000001FF
+000000000000000000000000000000000000000001FE0000000000000000000000000000
+00000000000003FE000000000000000000000000000000000000000007FC000000000000
+000000000000000000000000000007F80000000000000000000000000000000000000000
+0FF000000000000000000000000000000000000000001FF0000000000000000000000000
+00000000000000001FE000000000000000000000000000000000000000003FC000000000
+000000000000000000000000000000007FC0000000000000000000000000000000000000
+00007F800000000000000000000000000000000000000000FF0000000000000000000000
+00000000000000000000FF000000000000000000000000000000000000000001FE000000
+000000000000000000000000000000000003FE0000000000000000000000000000000000
+00000003FC000000000000000000000000000000000000000007F8000000000000000000
+000000000000000000000007F800000000000000000000000000000000000000000FF000
+000000000000000000000000000000000000000FF0000000000000000000000000000000
+00000000001FE000000000000000000000000000000000000000001FE000000000000000
+000000000000000000000000003FC000000000000000000000000000000000000000003F
+C000000000000000000000000000000000000000007F8000000000000000000000000000
+000000000000007F800000000000000000000000000000000000000000FF000000000000
+000000000000000000000000000000FF0000000000000000000000000000000000000000
+01FE000000000000000000000000000000000000000001FE000000000000000000000000
+000000000000000003FC000000000000000000000000000000000000000003FC00000000
+0000000000000000000000000000000007F8000000000000000000000000000000000000
+000007F8000000000000000000000000000000000000000007F000000000000000000000
+000000000000000000000FF000000000000000000000000000000000000000000FF00000
+0000000000000000000000000000000000001FE000000000000000000000000000000000
+000000001FE000000000000000000000000000000000000000001FC00000000000000000
+0000000000000000000000003FC000000000000000000000000000000000000000003FC0
+00000000000000000000000000000000000000007F800000000000000000000000000000
+0000000000007F8000000000000000000000000000000000000000007F00000000000000
+0000000000000000000000000000FF000000000000000000000000000000000000000000
+FF000000000000000000000000000000000000000000FE00000000000000000000000000
+0000000000000001FE000000000000000000000000000000000000000001FE0000000000
+00000000000000000000000000000001FC00000000000000000000000000000000000000
+0001FC000000000000000000000000000000000000000003FC0000000000000000000000
+00000000000000000003FC000000000000000000000000000000000000000003F8000000
+000000000000000000000000000000000007F80000000000000000000000000000000000
+00000007F8000000000000000000000000000000000000000007F0000000000000000000
+000000000000000000000007F000000000000000000000000000000000000000000FF000
+000000000000000000000000000000000000000FF0000000000000000000000000000000
+00000000000FE000000000000000000000000000000000000000000FE000000000000000
+000000000000000000000000000FE000000000000000000000000000000000000000001F
+E000000000000000000000000000000000000000001FE000000000000000000000000000
+000000000000001FC000000000000000000000000000000000000000001FC00000000000
+0000000000000000000000000000001FC000000000000000000000000000000000000000
+003FC000000000000000000000000000000000000000003FC00000000000000000000000
+0000000000000000003F8000000000000000000000000000000000000000003F80000000
+00000000000000000000000000000000003F800000000000000000000000000000000000
+0000003F8000000000000000000000000000000000000000007F80000000000000000000
+00000000000000000000007F8000000000000000000000000000000000000000007F0000
+000000000000000000000000000000000000007F00000000000000000000000000000000
+00000000007F0000000000000000000000000000000000000000007F0000000000000000
+000000000000000000000000007F0000000000000000000000000000000000000000007F
+0000000000000000000000000000000000000000007F0000000000000000000000000000
+000000000000007F000000000000000000000000000000000000000000FF000000000000
+000000000000000000000000000000FF0000000000000000000000000000000000000000
+00FE000000000000000000000000000000000000000000FE000000000000000000000000
+000000000000000000FE000000000000000000000000000000000000000000FE00000000
+0000000000000000000000000000000000FE000000000000000000000000000000000000
+000000FE000000000000000000000000000000000000000000FE00000000000000000000
+0000000000000000000000FE000000000000000000000000000000000000000000FE0000
+00000000000000000000000000000000000000FE00000000000000000000000000000000
+0000000000FE000000000000000000000000000000000000000000FE0000000000000000
+00000000000000000000000000FE0000000000000000000000000000000000000000007C
+0000000000000000000000000000000000000000003C0000000000000000000000000000
+00000000000000>173 173 128 134 332 I E /Fj 133[40 40
+1[40 40 40 40 40 40 1[40 40 40 40 40 40 1[40 40 40 40
+40 40 40 40 40 10[40 40 40 40 40 1[40 40 40 40 1[40 1[40
+1[40 40 40 40 40 40 7[40 40 40 40 40 40 40 40 40 40 40
+40 40 40 40 40 40 40 40 2[40 1[40 35[{TeXBase1Encoding ReEncodeFont}61
+66.666667 /Courier rf /Fk 145[33 48 1[29 107[{}3 66.666667
+/Times-Italic rf /Fl 194[31 61[{}1 66.666667 /RMTMI rf
+/Fm 205[28 28 49[{TeXBase1Encoding ReEncodeFont}2 56.666690
+/Times-Roman rf /Fn 205[32 32 49[{TeXBase1Encoding ReEncodeFont}2
+63.333383 /Times-Roman rf /Fo 139[23 32 32 1[42 1[46
+65 23 2[23 46 42 1[37 42 2[42 18[60 74 5[60 55 23[21
+46[{TeXBase1Encoding ReEncodeFont}18 83.333337 /Times-BoldItalic
+rf /Fp 133[50 50 50 50 50 50 50 50 50 1[50 50 50 50 50
+50 50 50 50 50 1[50 50 50 50 50 3[50 1[50 6[50 50 4[50
+1[50 2[50 7[50 14[50 50 1[50 50 50 45[{TeXBase1Encoding ReEncodeFont}37
+83.333337 /Courier rf /Fq 182[22 3[53 69[{TeXBase1Encoding ReEncodeFont}
+2 79.999924 /Helvetica-Bold rf /Fr 134[55 55 1[55 61
+33 55 39 1[61 61 61 89 28 1[28 28 61 61 1[55 61 55 61
+55 12[61 66 72 1[66 78 1[83 3[28 1[78 61 1[72 72 1[72
+8[55 55 55 55 55 55 55 55 2[28 33 5[28 39[{
+TeXBase1Encoding ReEncodeFont}44 100.000003 /Helvetica-Bold
+rf /Fs 103[28 30[37 37 55 37 42 23 32 32 1[42 42 42 60
+23 1[23 23 42 42 23 37 42 37 42 42 3[32 1[32 4[51 1[46
+3[51 60 55 69 5[60 51 51 1[55 2[76 2[56 2[28 5[42 1[42
+42 42 23 21 28 1[56 7[42 31[42 3[{TeXBase1Encoding ReEncodeFont}49
+83.333337 /Times-Italic rf /Ft 135[37 2[42 6[42 60 1[37
+23 23 3[37 42 2[42 10[51 5[51 1[55 6[60 1[51 3[51 65[{}16
+83.333337 /Times-Italic rf /Fu 136[61 40 55[65 2[27 23
+10[31 31 46[{}7 83.333337 /RMTMI rf /Fv 182[15 3[36 69[{
+ TeXBase1Encoding ReEncodeFont }2 66.666667 /Helvetica-Narrow
+rf /Fw 212[78 43[{}1 83.333337 /ZapfDingbats rf /Fx 134[34
+34 49 34 38 19 34 23 38 38 38 38 57 15 2[15 38 38 19
+38 38 34 38 38 12[42 45 49 2[53 1[57 9[49 1[45 10[38
+38 2[38 38 38 1[19 23 3[23 23 37[34 2[{ TeXBase1Encoding ReEncodeFont }
+40 83.333337 /Helvetica-Narrow rf /Fy 138[42 2[26 5[19
+2[19 1[42 1[38 2[42 38 12[42 13[42 12[38 38 38 38 38
+38 38 38 38 38 48[{ TeXBase1Encoding ReEncodeFont }20
+83.333337 /Helvetica-Narrow-Bold rf /Fz 134[42 1[60 42
+46 23 42 28 1[46 46 46 69 18 42 1[18 46 46 1[46 46 42
+46 46 7[55 1[78 55 1[51 55 60 1[55 1[60 69 1[55 1[23
+60 65 1[55 60 60 1[55 22[32 42[{TeXBase1Encoding ReEncodeFont}39
+83.333337 /Helvetica rf /FA 182[26 3[62 69[{
+TeXBase1Encoding ReEncodeFont}2 93.333301 /Helvetica-Bold
+rf /FB 133[42 46 46 65 46 51 28 46 32 1[51 51 51 74 23
+46 1[23 51 51 28 46 51 46 51 46 9[78 55 1[51 55 60 1[55
+65 60 69 1[60 1[23 1[65 51 55 60 60 60 2[51 8[46 46 46
+1[46 46 2[23 28 45[{TeXBase1Encoding ReEncodeFont}49
+83.333337 /Helvetica-Bold rf /FC 133[37 42 42 60 42 46
+28 32 37 46 46 42 46 69 23 1[28 23 46 42 28 37 46 37
+46 42 9[83 60 1[55 46 60 1[51 1[60 1[55 2[32 5[60 1[60
+8[42 1[42 42 42 42 42 42 3[28 21 4[28 5[28 29[46 46 2[{
+TeXBase1Encoding ReEncodeFont}49 83.333337 /Times-Bold
+rf /FD 134[65 1[90 1[71 39 65 45 71 1[71 71 103 32 2[32
+71 71 39 65 71 65 71 65 9[110 78 1[71 78 84 1[78 1[84
+97 71 2[32 5[84 1[84 10[65 65 65 65 65 65 3[39 5[32 39[{
+TeXBase1Encoding ReEncodeFont}40 116.666669 /Helvetica-Bold
+rf /FE 103[22 30[37 1[52 1[41 22 37 26 1[41 1[41 59 1[37
+1[18 41 2[37 41 37 1[37 23[18 3[44 10[22 10[18 18 46[{
+TeXBase1Encoding ReEncodeFont}22 66.666667 /Helvetica-Bold
+rf /FF 133[29 33 1[48 33 33 18 26 22 33 33 33 33 52 18
+33 1[18 33 33 22 29 33 29 33 29 9[63 1[48 41 37 44 1[37
+48 1[59 41 2[22 48 48 37 1[48 44 44 48 6[18 33 33 2[33
+33 33 33 33 33 18 17 22 17 6[55 33[37 37 2[{
+TeXBase1Encoding ReEncodeFont}57 66.666667 /Times-Roman
+rf /FG 171[41 44 5[55 3[18 3[44 69[{TeXBase1Encoding ReEncodeFont}5
+66.666667 /Helvetica rf /FH 182[15 3[35 69[{
+TeXBase1Encoding ReEncodeFont}2 53.333281 /Helvetica
+rf /FI 252[29 3[{}1 56.666690 /MTSYN rf /FJ 134[33 33
+50 33 37 21 29 29 1[37 37 37 54 21 33 1[21 37 37 21 33
+37 33 37 37 25 5[42 5[42 37 2[46 2[62 42 1[33 25 1[54
+1[46 54 50 1[46 6[25 11[19 6[25 36[37 2[{TeXBase1Encoding ReEncodeFont}
+41 75.000000 /Times-Italic rf /FK 103[25 1[37 27[33 37
+37 54 37 37 21 29 25 37 37 37 37 58 21 37 21 21 37 37
+25 33 37 33 37 33 3[25 1[25 3[71 54 54 46 42 50 1[42
+1[54 66 46 54 29 25 54 54 1[46 54 50 50 54 6[21 37 37
+37 37 37 37 37 37 37 37 21 19 25 19 2[25 25 25 39[{
+TeXBase1Encoding ReEncodeFont}68 75.000000 /Times-Roman
+rf /FL 104[83 28[37 42 42 60 42 42 23 32 28 42 42 42
+42 65 23 42 23 23 42 42 28 37 42 37 42 37 28 2[28 1[28
+2[60 78 60 60 51 46 55 1[46 60 60 74 51 60 1[28 60 60
+46 51 60 55 55 60 76 2[47 1[23 23 42 42 42 42 42 42 42
+42 42 42 23 21 28 21 1[42 28 28 28 65 69 33[46 46 2[{
+TeXBase1Encoding ReEncodeFont}78 83.333337 /Times-Roman
+rf /FM 149[24 2[31 31 16[28 28 15[65 65 12[0 3[52 85
+22[65 22[43 3[{}12 83.333337 /MTSYN rf /FN 134[50 2[50
+50 28 39 33 1[50 50 50 78 28 2[28 50 1[33 44 1[44 50
+44 11[72 1[55 66 1[55 1[72 89 4[72 3[72 66 1[72 7[50
+50 2[50 50 1[50 50 50 28 2[25 44[{TeXBase1Encoding ReEncodeFont}37
+100.000003 /Times-Roman rf /FO 134[60 3[66 1[60 40 1[66
+66 66 100 3[27 1[66 1[66 66 2[66 10[80 10[80 3[93 71[{
+TeXBase1Encoding ReEncodeFont}16 119.999948 /Helvetica
+rf /FP 140[53 38 2[77 72 4[29 3[77 14[84 33[67 3[67 1[33
+46[{TeXBase1Encoding ReEncodeFont}10 119.999948 /AvantGarde-Demi
+rf /FQ 136[115 1[86 43 63 46 1[95 92 86 135 34 83 1[34
+86 95 40 92 95 92 1[95 11[92 1[75 83 1[80 121 1[129 5[121
+69 2[112 1[106 19[60 40 44[{TeXBase1Encoding ReEncodeFont}31
+143.999997 /AvantGarde-Demi rf /FR 252[66 3[{}1 126.665747
+/MTSYN rf /FS 171[126 138 5[172 77[{TeXBase1Encoding ReEncodeFont}3
+207.333362 /Helvetica-Bold rf /FT 182[46 3[110 69[{
+TeXBase1Encoding ReEncodeFont}2 165.866715 /Helvetica-Bold
+rf end
+%%EndProlog
+%%BeginSetup
+%%Feature: *Resolution 600dpi
+TeXDict begin
+%%PaperSize: Letter
+
+%%EndSetup
+%%Page: 1 1
+1 0 bop 1700 560 a FS(M)-11 b FT(E)-42 b FS(T)g FT(I)p
+FS(S)2202 499 y FR(\003)280 760 y FQ(A)40 b(Softw)l(ar)o(e)f(P)m(ac)n
+(kage)g(f)m(or)i(P)m(ar)s(titioning)g(Unstr)s(uctur)o(ed)399
+961 y(Gra)s(phs)s(,)e(P)m(ar)s(titioning)i(Meshes)s(,)g(and)e
+(Computing)484 1162 y(Fill-Reducing)i(Or)o(der)s(ings)f(of)g(Spar)s(se)
+f(Ma)q(tr)s(ices)1640 1363 y FP(V)-12 b(er)r(sion)32
+b(4.0)1076 1749 y FO(George)j(Kar)t(ypis)e(and)h(Vipin)f(K)l(umar)167
+1929 y FN(Uni)n(v)o(ersity)23 b(of)i(Minnesota,)e(Department)h(of)h
+(Computer)g(Science)g(/)g(Army)f(HPC)i(Research)g(Center)1459
+2057 y(Minneapolis,)d(MN)h(55455)1443 2214 y FM(f)p FL(karypis,)19
+b(kumar)p FM(g)p FL(@cs.umn.edu)1550 2406 y FN(September)25
+b(20,)g(1998)208 2756 y FK(Metis)16 b([MEE)g(tis]:)21
+b FJ(`Metis')16 b(is)g(the)h(Gr)m(eek)g(wor)m(d)g(for)g(wisdom.)22
+b(Metis)16 b(was)h(a)f(titaness)h(in)f(Gr)m(eek)i(mytholo)o(gy)l(.)23
+b(She)17 b(was)g(the)f(consort)208 2856 y(of)i(Zeus)h(and)h(the)f
+(mother)g(of)g(Athena.)24 b(She)19 b(pr)m(esided)h(o)o(ver)g(all)f
+(wisdom)g(and)h(knowledg)o(e)o(.)p 0 4929 1560 4 v 86
+4981 a FI(\003)122 5005 y FG(M)m FH(E)-13 b FG(T)g FH(I)q
+FG(S)18 b FF(is)h(cop)o(yrighted)j(by)d(the)h(re)o(gents)g(of)f(the)h
+(Uni)n(v)o(ersity)h(of)e(Minnesota.)28 b(This)19 b(w)o(ork)g(w)o(as)h
+(supported)g(by)f(IST/BMDO)g(through)h(Army)f(Research)i(Of)n(\002ce)0
+5084 y(contract)d(D)m(A/D)m(AAH04-93-G-0080,)g(and)d(by)h(Army)f(High)g
+(Performance)i(Computing)g(Research)h(Center)f(under)f(the)g(auspices)h
+(of)e(the)h(Department)h(of)f(the)g(Army)l(,)0 5163 y(Army)i(Research)i
+(Laboratory)g(cooperati)n(v)o(e)i(agreement)e(number)f(D)m
+(AAH04-95-2-0003/contract)24 b(number)18 b(D)m(AAH04-95-C-0008,)j(the)e
+(content)h(of)e(which)h(does)0 5242 y(not)g(necessarily)i(re\003ect)f
+(the)f(position)h(or)e(the)h(polic)o(y)h(of)e(the)h(go)o(v)o(ernment,)h
+(and)f(no)f(of)n(\002cial)i(endorsement)h(should)e(be)f(inferred.)26
+b(Access)19 b(to)g(computing)h(f)o(acilities)0 5321 y(were)14
+b(pro)o(vided)h(by)e(Minnesota)i(Supercomputer)h(Institute,)f(Cray)f
+(Research)h(Inc,)f(and)g(by)f(the)h(Pittsb)o(ur)o(gh)g(Supercomputing)i
+(Center)l(.)22 b(Related)15 b(papers)f(are)g(a)o(v)n(ailable)0
+5400 y(via)k(WWW)d(at)j(URL:)f FE(http://www)m(.cs.umn.edu/\230kar)q
+(ypis)1929 5649 y FL(1)p eop
+%%Page: 2 2
+2 1 bop 0 85 a FD(Contents)0 277 y FC(1)83 b(Intr)o(oduction)3281
+b(3)0 470 y(2)83 b(What)20 b(is)j FB(M)l FE(E)-17 b FB(T)g
+FE(I)p FB(S)3237 b FC(4)0 663 y(3)83 b(What)20 b(is)h(New)f(in)h(This)h
+(V)-8 b(ersion)2724 b(6)0 855 y(4)85 b FB(M)l FE(E)-17
+b FB(T)g FE(I)p FB(S)r FC(')m(s)22 b(Stand-Alone)d(Pr)o(ograms)2637
+b(8)125 965 y FL(4.1)85 b(Graph)20 b(P)o(artitioning)e(Programs)53
+b(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)
+f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g
+(.)h(.)f(.)g(.)g(.)143 b(8)125 1074 y(4.2)85 b(Mesh)21
+b(P)o(artitioning)d(Programs)76 b(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)
+h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g
+(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)143
+b(9)125 1184 y(4.3)85 b(Sparse)21 b(Matrix)e(Reordering)g(Programs)58
+b(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)
+f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g
+(.)102 b(11)125 1294 y(4.4)85 b(Auxiliary)19 b(Programs)43
+b(.)e(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h
+(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)
+g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(13)315 1403
+y(4.4.1)c(Mesh)20 b(T)-7 b(o)21 b(Graph)e(Con)m(v)o(ersion)75
+b(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)
+f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g
+(.)102 b(13)315 1513 y(4.4.2)c(Graph)19 b(Check)o(er)56
+b(.)41 b(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)
+g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h
+(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(14)125 1622 y(4.5)85
+b(Input)19 b(File)i(F)o(ormats)h(.)41 b(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g
+(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)
+f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g
+(.)102 b(15)315 1732 y(4.5.1)c(Graph)19 b(File)79 b(.)41
+b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f
+(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)
+h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(15)315 1842 y(4.5.2)c(Mesh)20
+b(File)40 b(.)h(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h
+(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)
+g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(16)125
+1951 y(4.6)85 b(Output)20 b(File)h(F)o(ormats)28 b(.)41
+b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f
+(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)
+h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(17)315 2061 y(4.6.1)c(P)o
+(artition)20 b(File)63 b(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g
+(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)
+f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102
+b(17)315 2170 y(4.6.2)c(Ordering)19 b(File)48 b(.)42
+b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g
+(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)
+f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(17)0 2363 y FC(5)85
+b FB(M)l FE(E)-17 b FB(T)g FE(I)p FB(S)r FC(')m(s)22
+b(Library)e(Interface)2784 b(18)125 2473 y FL(5.1)85
+b(Graph)20 b(Data)g(Structure)52 b(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g
+(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)
+g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102
+b(18)125 2582 y(5.2)85 b(Mesh)21 b(Data)f(Structure)75
+b(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)
+f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g
+(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(19)125 2692
+y(5.3)85 b(P)o(artitioning)19 b(Objecti)n(v)o(es)62 b(.)41
+b(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g
+(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)
+g(.)g(.)h(.)f(.)g(.)g(.)102 b(19)125 2801 y(5.4)85 b(Graph)20
+b(P)o(artitioning)e(Routines)77 b(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)
+h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g
+(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102
+b(21)504 2911 y(METIS)p 759 2911 25 4 v 29 w(P)o(artGraphRecursi)n(v)o
+(e)60 b(.)41 b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g
+(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)
+f(.)g(.)g(.)102 b(21)504 3020 y(METIS)p 759 3020 V 29
+w(P)o(artGraphKw)o(ay)68 b(.)41 b(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g
+(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)
+f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(22)504
+3130 y(METIS)p 759 3130 V 29 w(P)o(artGraphVKw)o(ay)70
+b(.)41 b(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)
+g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f
+(.)g(.)g(.)102 b(23)504 3240 y(METIS)p 759 3240 V 29
+w(mCP)o(artGraphRecursi)n(v)o(e)65 b(.)41 b(.)g(.)g(.)h(.)f(.)g(.)h(.)f
+(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)
+h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(24)504 3349 y(METIS)p
+759 3349 V 29 w(mCP)o(artGraphKw)o(ay)72 b(.)41 b(.)h(.)f(.)g(.)g(.)h
+(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)
+g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(26)504
+3459 y(METIS)p 759 3459 V 29 w(WP)o(artGraphRecursi)n(v)o(e)44
+b(.)e(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f
+(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)
+102 b(28)504 3568 y(METIS)p 759 3568 V 29 w(WP)o(artGraphKw)o(ay)52
+b(.)41 b(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)
+g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f
+(.)g(.)g(.)102 b(30)504 3678 y(METIS)p 759 3678 V 29
+w(WP)o(artGraphVKw)o(ay)54 b(.)41 b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f
+(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)
+h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(32)125 3788 y(5.5)85
+b(Mesh)21 b(P)o(artitioning)d(Routines)38 b(.)j(.)h(.)f(.)g(.)g(.)h(.)f
+(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)
+h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102
+b(34)504 3897 y(METIS)p 759 3897 V 29 w(P)o(artMeshNodal)23
+b(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)
+f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g
+(.)h(.)f(.)g(.)g(.)102 b(34)504 4007 y(METIS)p 759 4007
+V 29 w(P)o(artMeshDual)65 b(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f
+(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)
+h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(35)125
+4116 y(5.6)85 b(Sparse)21 b(Matrix)e(Reordering)g(Routines)h(.)41
+b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f
+(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)
+102 b(36)504 4226 y(METIS)p 759 4226 V 29 w(EdgeND)67
+b(.)41 b(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)
+g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h
+(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(36)504 4336 y(METIS)p
+759 4336 V 29 w(NodeND)58 b(.)41 b(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g
+(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)
+f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102
+b(37)504 4445 y(METIS)p 759 4445 V 29 w(NodeWND)42 b(.)f(.)g(.)h(.)f(.)
+g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h
+(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)
+g(.)102 b(39)125 4555 y(5.7)85 b(Auxiliary)19 b(Routines)67
+b(.)41 b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)
+h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f
+(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(40)504 4664
+y(METIS)p 759 4664 V 29 w(MeshT)-7 b(oNodal)70 b(.)42
+b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g
+(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)
+f(.)g(.)g(.)102 b(40)504 4774 y(METIS)p 759 4774 V 29
+w(MeshT)-7 b(oDaul)50 b(.)41 b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f
+(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)
+h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(41)504
+4883 y(METIS)p 759 4883 V 29 w(EstimateMemory)29 b(.)41
+b(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g
+(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)
+g(.)g(.)102 b(42)125 4993 y(5.8)85 b(C)22 b(and)d(F)o(ortran)g(Support)
+81 b(.)41 b(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f
+(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)
+h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(43)0 5186 y FC(6)83
+b(System)20 b(Requir)o(ements)g(and)h(Contact)e(Inf)n(ormation)2011
+b(44)1929 5649 y FL(2)p eop
+%%Page: 3 3
+3 2 bop 0 85 a FD(1)116 b(Intr)n(oduction)0 261 y FL(Algorithms)17
+b(that)h(\002nd)g(a)h(good)d(partitioning)g(of)i(highly)f(unstructured)
+f(graphs)h(are)h(critical)g(for)g(de)n(v)o(eloping)d(ef)n(\002cient)j
+(solutions)f(for)0 370 y(a)25 b(wide)f(range)f(of)g(problems)g(in)h
+(man)o(y)f(application)g(areas)h(on)g(both)f(serial)i(and)e(parallel)h
+(computers.)35 b(F)o(or)24 b(e)o(xample,)f(lar)o(ge-scale)0
+480 y(numerical)f(simulations)h(on)g(parallel)h(computers,)e(such)i(as)
+g(those)f(based)h(on)f(\002nite)h(element)f(methods,)g(require)f(the)i
+(distrib)n(ution)0 590 y(of)e(the)h(\002nite)g(element)f(mesh)g(to)h
+(the)g(processors.)31 b(This)22 b(distrib)n(ution)g(must)g(be)h(done)e
+(so)i(that)g(the)g(number)d(of)j(elements)f(assigned)0
+699 y(to)28 b(each)g(processor)e(is)j(the)f(same,)h(and)f(the)g(number)
+e(of)h(adjacent)g(elements)h(assigned)f(to)h(dif)n(ferent)e(processors)
+h(is)i(minimized.)0 809 y(The)20 b(goal)g(of)h(the)f(\002rst)h
+(condition)e(is)j(to)e(balance)g(the)g(computations)f(among)g(the)i
+(processors.)k(The)20 b(goal)g(of)g(the)h(second)e(condition)0
+918 y(is)25 b(to)g(minimize)e(the)h(communication)e(resulting)h(from)g
+(the)i(placement)e(of)h(adjacent)f(elements)h(to)h(dif)n(ferent)d
+(processors.)37 b(Graph)0 1028 y(partitioning)20 b(can)h(be)g(used)h
+(to)f(successfully)g(satisfy)h(these)g(conditions)e(by)h(\002rst)h
+(modeling)e(the)h(\002nite)h(element)f(mesh)g(by)g(a)h(graph,)0
+1138 y(and)e(then)f(partitioning)g(it)h(into)g(equal)g(parts.)100
+1247 y(Graph)31 b(partitioning)g(algorithms)g(are)h(also)h(used)f(to)h
+(compute)e(\002ll-reducing)f(orderings)h(of)h(sparse)g(matrices.)62
+b(These)32 b(\002ll-)0 1357 y(reducing)d(orderings)f(are)j(useful)f
+(when)g(direct)g(methods)g(are)g(used)h(to)f(solv)o(e)h(sparse)f
+(systems)h(of)g(linear)f(equations.)55 b(A)31 b(good)0
+1466 y(ordering)25 b(of)i(a)h(sparse)f(matrix)g(dramatically)f(reduces)
+g(both)h(the)g(amount)f(of)h(memory)f(as)i(well)g(as)g(the)f(time)h
+(required)d(to)j(solv)o(e)0 1576 y(the)23 b(system)g(of)g(equations.)32
+b(Furthermore,)21 b(the)i(\002ll-reducing)e(orderings)h(produced)e(by)j
+(graph)e(partitioning)g(algorithms)h(are)h(par)n(-)0
+1685 y(ticularly)28 b(suited)h(for)g(parallel)g(direct)f(f)o
+(actorization)g(as)i(the)o(y)e(lead)h(to)g(high)f(de)o(gree)g(of)h
+(concurrenc)o(y)d(during)h(the)i(f)o(actorization)0 1795
+y(phase.)100 1905 y(Graph)19 b(partitioning)f(is)j(also)g(used)e(for)h
+(solving)f(optimization)g(problems)f(arising)i(in)g(numerous)e(areas)j
+(such)f(as)g(design)g(of)g(v)o(ery)0 2014 y(lar)o(ge)25
+b(scale)i(inte)o(grated)e(circuits)h(\(VLSI\),)f(storing)g(and)h
+(accessing)g(spatial)h(databases)e(on)h(disks,)i(transportation)c
+(management,)0 2124 y(and)c(data)g(mining.)1929 5649
+y(3)p eop
+%%Page: 4 4
+4 3 bop 0 85 a FD(2)116 b(What)31 b(is)k(M)-6 b FA(E)-23
+b FD(T)g FA(I)p FD(S)2 259 y Fz(M)l FG(E)-17 b Fz(T)g
+FG(I)p Fz(S)34 b FL(is)d(a)f(softw)o(are)f(package)f(for)h
+(partitioning)f(lar)o(ge)h(irre)o(gular)f(graphs,)i(partitioning)e(lar)
+o(ge)h(meshes,)i(and)f(computing)d(\002ll-)0 369 y(reducing)21
+b(orderings)g(of)i(sparse)g(matrices.)32 b(The)23 b(algorithms)f(in)j
+Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)27 b FL(are)c(based)f(on)h
+(multile)n(v)o(el)e(graph)h(partitioning)f(described)0
+478 y(in)30 b([8)o(,)f(7,)h(6)o(].)53 b(T)m(raditional)28
+b(graph)g(partitioning)f(algorithms)h(compute)g(a)i(partition)e(of)h(a)
+h(graph)e(by)h(operating)e(directly)i(on)g(the)0 588
+y(original)17 b(graph)h(as)h(illustrated)f(in)h(Figure)f(1\(a\).)24
+b(These)18 b(algorithms)g(are)g(often)g(too)g(slo)n(w)h(and/or)f
+(produce)e(poor)i(quality)g(partitions.)100 698 y(Multile)n(v)o(el)23
+b(partitioning)g(algorithms,)h(on)g(the)g(other)g(hand,)g(tak)o(e)g(a)h
+(completely)e(dif)n(ferent)g(approach)f([5)o(,)j(8)o(,)g(7)o(].)38
+b(These)24 b(algo-)0 807 y(rithms,)19 b(as)h(illustrated)f(in)g(Figure)
+f(1\(b\),)g(reduce)g(the)i(size)g(of)e(the)i(graph)d(by)i(collapsing)f
+(v)o(ertices)h(and)g(edges,)f(partition)g(the)i(smaller)0
+917 y(graph,)25 b(and)f(then)h(uncoarsen)e(it)j(to)g(construct)e(a)h
+(partition)f(for)h(the)g(original)f(graph.)40 b Fz(M)l
+FG(E)-17 b Fz(T)g FG(I)p Fz(S)30 b FL(uses)c(no)o(v)o(el)d(approaches)g
+(to)j(succes-)0 1026 y(si)n(v)o(ely)h(reduce)f(the)h(size)g(of)g(the)g
+(graph)f(as)i(well)f(as)h(to)f(further)f(re\002ne)h(the)g(partition)f
+(during)f(the)i(uncoarsening)e(phase.)45 b(During)0 1136
+y(coarsening,)19 b Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)24
+b FL(emplo)o(ys)19 b(algorithms)f(that)h(mak)o(e)g(it)h(easier)g(to)f
+(\002nd)g(a)h(high-quality)d(partition)h(at)i(the)f(coarsest)h(graph.)j
+(During)0 1246 y(re\002nement,)h Fz(M)l FG(E)-17 b Fz(T)g
+FG(I)p Fz(S)28 b FL(focuses)23 b(primarily)e(on)i(the)h(portion)d(of)i
+(the)g(graph)f(that)i(is)g(close)f(to)h(the)f(partition)f(boundary)-5
+b(.)31 b(These)23 b(highly)0 1355 y(tuned)c(algorithms)g(allo)n(w)j
+Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)25 b FL(to)20 b(quickly)f(produce)
+f(high-quality)g(partitions)h(for)h(a)g(lar)o(ge)g(v)n(ariety)f(of)h
+(graphs.)450 2607 y @beginspecial 0 @llx 0 @lly 1129
+@urx 433 @ury 3600 @rwi @setspecial
+%%BeginDocument: ./figures/slide78.eps
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {} def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+-48.0 455.0 translate
+1 -1 scale
+
+/clp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+  bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+  4 -2 roll mul srgb} bind def
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+10 setmiterlimit
+ 0.06000 0.06000 sc
+% Polyline
+%
+% Begin Imported EPS File: slide7.eps
+%
+n gs
+825 1606 tr
+15.284974 -15.278970 sc
+0 -233 tr
+-35 -330 tr
+save
+/showpage {} def
+% EPS file follows:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/defineresource where{pop}{userdict begin/defineresource{userdict/Resources 2
+
+copy known{get begin}{15 dict dup begin put}ifelse exch readonly exch
+
+currentdict 1 index known not{dup 30 dict def}if load 3 -1 roll 2 index put
+
+end}bind readonly def/findresource{userdict/Resources get exch get exch get}
+
+bind readonly def/resourceforall{pop pop pop pop}bind readonly def
+
+/resourcestatus{userdict/Resources 2 copy known{get exch 2 copy known{get exch
+
+known{0 -1 true}{pop pop false}ifelse}{pop pop pop false}ifelse}{pop pop false
+
+}ifelse}bind readonly def end}ifelse
+
+
+
+/Pscript_Win_Driver 200 dict dup begin
+
+
+/FatalErrorIf{{initgraphics findfont exch scalefont setfont counttomark 3 div
+
+cvi{moveto show}repeat showpage quit}{cleartomark}ifelse}bind def
+
+
+/VM? {vmstatus exch sub exch pop gt { [
+
+(This job requires more memory than is available in this printer.) 100 500
+
+(Try one or more of the following, and then print again:) 100 485
+
+(In the PostScript dialog box, click Optimize For Portability.) 115 470
+
+(In the Device Options dialog box, make sure the Available Printer Memory is accurate.) 115 455
+
+(Reduce the number of fonts in the document.) 115 440
+
+(Print the document in parts.) 115 425
+
+12 /Times-Roman showpage
+
+(%%[ PrinterError: Low Printer VM ]%%) =
+
+true FatalErrorIf}if} bind def
+
+
+/|/def load def/,/load load |/~/exch , |/?/ifelse , |/!/pop , |/`/begin , |/^
+
+/index , |/@/dup , |/+/translate , |/$/roll , |/U/userdict , |/M/moveto , |/-
+
+/rlineto , |/&/currentdict , |/:/gsave , |/;/grestore , |/F/false , |/T/true ,
+
+|/N/newpath , |/E/end , |/Ac/arc , |/An/arcn , |/A/ashow , |/D/awidthshow , |
+
+/C/closepath , |/V/div , |/O/eofill , |/L/fill , |/I/lineto , |/-C/rcurveto ,
+
+|/-M/rmoveto , |/+S/scale , |/Ji/setfont , |/Lc/setlinecap , |/Lj/setlinejoin
+
+, |/Lw/setlinewidth , |/S/show , |/LH/showpage , |/K/stroke , |/W/widthshow ,
+
+|/R/rotate , |/b{bind |}bind |/bd{bind |}bind |/xd{~ |}bd/ld{, |}bd/lw/Lw ld
+
+/lc/Lc ld/lj/Lj ld/sg/setgray ld/L2? F/languagelevel where{! languagelevel 2
+
+ge{! T}if}if |/g{@ not{U/DefIf_save save put}if U/DefIf_bool 2 ^ put}b
+
+/DefIf_El{if U/DefIf_bool get not @{U/DefIf_save get restore}if}b/e{DefIf_El !
+
+}b/self & |/reinitialize{[/TextInit/GraphInit/UtilsInit counttomark{@ where{
+
+self eq}{F}?{cvx exec}{!}?}repeat cleartomark}b/initialize{`{/ADO_mxRot ~ |
+
+/TextInitialised? F | reinitialize E}{U/Pscript_Win_Data 200 dict @ ` put
+
+/ADO_mxRot ~ |/TextInitialised? F | reinitialize}?}b/terminate{!{& self eq{
+
+exit}{E}?}loop E}b/suspend/terminate , |/resume{` Pscript_Win_Data `}b/snap{
+
+transform 0.25 sub round 0.25 add ~ 0.25 sub round 0.25 add ~ itransform}b
+
+/dsnap{dtransform round ~ round ~ idtransform}b<04>cvn{}|/setjn{{statusdict
+
+/jobname known{statusdict/jobname 3 -1 $ put}if}stopped cleartomark}b/solid{[]
+
+0 setdash}b/setdsh{0 setdash}b/colspRefresh{}b/rp{4 2 $ M 1 ^ 0 - 0 ~ - neg 0
+
+-}b/rr{1 ^ 0 - 0 ~ - neg 0 - C}b
+
+
+
+L2? not g{/rf{N rp L}b/fx{1 1 dtransform @ 0 ge{1 sub 1}{1 add -0.25}? 3 -1 $
+
+@ 0 ge{1 sub 1}{1 add -0.25}? 3 1 $ 4 1 $ idtransform 4 -2 $ idtransform}b/BZ{
+
+4 -2 $ snap + +S fx rf}b/rs{N rp C K}b/rc{N rp clip N}b/sg{setgray}b/sco{
+
+setrgbcolor}b/sgco{{sg}{sco}?}b}e
+
+
+
+L2? g{/colspA/DeviceGray |/colspABC/DeviceRGB |/setAorABC{{colspA}{colspABC}?
+
+setcolorspace}b/rf/rectfill , |/fx{1 1 dtransform @ 0 ge{1 sub 0.5}{1 add -0.5
+
+}? 3 -1 $ @ 0 ge{1 sub 0.5}{1 add -0.5}? 3 1 $ 4 1 $ idtransform 4 -2 $
+
+idtransform}b/BZ{4 -2 $ snap + +S fx rf}b/rs/rectstroke , |/rc/rectclip , |/sg
+
+{@ @ setcolor}b/sco{setcolor}b/colspRefresh{colspABC setcolorspace}b/sgco{{sg
+
+}{sco}?}b/UtilsInit{F setglobal}b/definecolorrendering{/ColorRendering
+
+defineresource !}b/findcolorrendering{@/ColorRendering resourcestatus{! !
+
+/ColorRendering findresource T}{! F}?}b/selectcolorrendering{@/ColorRendering
+
+resourcestatus{! !/ColorRendering}{!/DefaultColorRendering/ColorRendering}?
+
+findresource setcolorrendering}b}e
+
+
+
+/bullets{{/bullet}repeat}b/ANSIEncoding[/grave/acute/circumflex/tilde/macron
+
+/breve/dotaccent/dieresis/ring/cedilla/hungarumlaut/ogonek/caron/dotlessi 18
+
+bullets StandardEncoding 32 95 getinterval aload ! 3 bullets/quotesinglbase
+
+/florin/quotedblbase/ellipsis/dagger/daggerdbl/circumflex/perthousand/Scaron
+
+/guilsinglleft/OE 4 bullets/quoteleft/quoteright/quotedblleft/quotedblright
+
+/bullet/endash/emdash/tilde/trademark/scaron/guilsinglright/oe 2 bullets
+
+/Ydieresis/space/exclamdown/cent/sterling/currency/yen/brokenbar/section
+
+/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered
+
+/macron/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph
+
+/periodcentered/cedilla/onesuperior/ordmasculine/guillemotright/onequarter
+
+/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis
+
+/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute
+
+/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
+
+/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
+
+/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute
+
+/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve
+
+/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex
+
+/udieresis/yacute/thorn/ydieresis]| ANSIEncoding @ 39/quotesingle put 96/grave
+
+put/ANSIEncodingOld ANSIEncoding 256 array copy | ANSIEncodingOld @[138 153
+
+154 169 172 174 177 178 179 181 185 188 189 190 208 215 221 222 240 247 253
+
+254]{/bullet put @}forall 166/bar put 176/ring put
+
+
+
+/TextInit{TextInitialised? not{/Pscript_Windows_Font & |/TextInitialised? T |
+
+/fM[1 0 0 -1 0 0]|/mFM matrix |/iMat[1 0 0.212557 neg 1 0 0]|}if}b/xUP null |
+
+/yUP null |/uW null |/xSP null |/ySP null |/sW null |/copyfont{1 ^ length add
+
+dict `{1 ^/FID ne{|}{! !}?}forall & E}b/rF{3 copyfont @ `/Encoding
+
+ANSIEncoding &/CharStrings known{CharStrings/Eth known not{! ANSIEncodingOld}
+
+if}if | E}b/mF{findfont ~{@/Encoding get @ StandardEncoding eq{! T}{{
+
+ISOLatin1Encoding}stopped{! F}{eq}?{T}{@ ` T 32 1 127{Encoding 1 ^ get
+
+StandardEncoding 3 -1 $ get eq and}for E}?}?}{F}?{rF}{3 copyfont}? `
+
+/OrigFontType ~ |/OrigFontName ~ | & E 2 ^ ~ definefont fM 5 4 -1 $ put fM 4 0
+
+put fM makefont Pscript_Windows_Font 3 1 $ put}b/xF{scalefont
+
+Pscript_Windows_Font 3 1 $ put}b/xMF{mFM astore makefont Pscript_Windows_Font
+
+3 1 $ put}b/xF2/scalefont , |/xMF2{mFM astore makefont}b/sLT{: Lw -M
+
+currentpoint snap M 0 - 0 Lc K ;}b/sSU{N/uW ~ |/yUP ~ |/xUP ~ |}b/sU{xUP yUP
+
+uW sLT}b/sST{N/sW ~ |/ySP ~ |/xSP ~ |}b/sT{xSP ySP sW sLT}b/sR{: + R 0 0 M}b
+
+/sRxy{: matrix astore concat 0 0 M}b/eR/; , |
+
+
+
+/mBF{@ 4 copyfont `/FontName ~ |/OrigFontType ~ |/OrigFontName ~ | 0
+
+FontMatrix idtransform ! &/PaintType known{PaintType 0 eq{/PaintType 2 |
+
+/StrokeWidth ~ |}{PaintType 1 eq PaintType 2 eq or PaintType 3 eq or &
+
+/StrokeWidth known and{StrokeWidth add/StrokeWidth ~ |}{!}?}?}{!}? @ & E
+
+definefont Pscript_Windows_Font 3 1 $ put}b/xBF{Pscript_Windows_Font ` 1 ^
+
+/FontName get 1 ^ scalefont 3 1 $ scalefont 2 copy ~ | ~ ! | E}b/xMBF{mFM
+
+astore Pscript_Windows_Font ` 1 ^/FontName get 1 ^ makefont 3 1 $ makefont 2
+
+copy ~ | ~ ! | E}b/xBF2{/sB0 ~ mBF/sB1 sB0 3 -1 $ xBF sB1}b/xMBF2{/sB0 ~ mBF
+
+mFM astore/sB1 sB0 3 -1 $ xMBF sB1}b/sB{: Pscript_Windows_Font currentfont get
+
+Ji @ S ; S}b/asB{: Pscript_Windows_Font currentfont get Ji 3 copy A ; A}b/wsB{
+
+: Pscript_Windows_Font currentfont get Ji 4 copy W ; W}b/awsB{:
+
+Pscript_Windows_Font currentfont get Ji 6 copy D ; D}b/sBT3{: @ S ; 1 1 -M S}b
+
+/asBT3{: 3 copy A ; 1 1 -M A}b/wsBT3{: 4 copy W ; 1 1 -M W}b/awsBT3{: 6 copy D
+
+; 1 1 -M D}b/mIF{iMat 4 3 -1 $ put 2 copyfont `/OrigFontType ~ |/OrigFontName
+
+~ | @ & E definefont iMat makefont Pscript_Windows_Font 3 1 $ put}b
+
+
+
+/SavedCTM null |/CTMsave{/SavedCTM SavedCTM currentmatrix |}b/CTMrestore{
+
+SavedCTM setmatrix}b/mp null |/ADO_mxRot null |/GDIHMatrix null |
+
+/GDIHPatternDict 22 dict | GDIHPatternDict `/PatternType 1 |/PaintType 2 |
+
+/Reps L2?{1}{5}? |/XStep 8 Reps mul |/YStep XStep |/BBox[0 0 XStep YStep]|
+
+/TilingType 1 |/PaintProc{` 1 Lw[]0 setdash PaintData , exec E}b/FGnd null |
+
+/BGnd null |/HS_Horizontal{horiz}b/HS_Vertical{vert}b/HS_FDiagonal{fdiag}b
+
+/HS_BDiagonal{biag}b/HS_Cross{horiz vert}b/HS_DiagCross{fdiag biag}b/MaxXYStep
+
+XStep YStep gt{XStep}{YStep}? |/horiz{Reps{0 4 M XStep 0 - 0 8 +}repeat 0 -8
+
+Reps mul + K}b/vert{Reps{4 0 M 0 YStep - 8 0 +}repeat 0 -8 Reps mul + K}b/biag
+
+{Reps{0 0 M MaxXYStep @ - 0 YStep neg M MaxXYStep @ - 0 8 +}repeat 0 -8 Reps
+
+mul + 0 YStep M 8 8 - K}b/fdiag{Reps{0 0 M MaxXYStep @ neg - 0 YStep M
+
+MaxXYStep @ neg - 0 8 +}repeat 0 -8 Reps mul + MaxXYStep @ M 8 -8 - K}b E
+
+/makehatch{GDIHPatternDict/PaintData 3 -1 $ put CTMsave GDIHMatrix setmatrix
+
+GDIHPatternDict matrix mp CTMrestore ~ U ~ 2 ^ put}b/h0{/h0/HS_Horizontal
+
+makehatch}b/h1{/h1/HS_Vertical makehatch}b/h2{/h2/HS_FDiagonal makehatch}b/h3{
+
+/h3/HS_BDiagonal makehatch}b/h4{/h4/HS_Cross makehatch}b/h5{/h5/HS_DiagCross
+
+makehatch}b/GDIBWPatternDict 17 dict @ `/PatternType 1 |/PaintType L2?{1}{2}?
+
+|/RepsV L2?{1}{6}? |/RepsH L2?{1}{5}? |/BBox[0 0 RepsH 1]|/TilingType 1 |
+
+/XStep 1 |/YStep 1 |/Height 8 RepsV mul |/Width 8 |/mx[Width 0 0 Height neg 0
+
+Height]|/FGnd null |/BGnd null |/SetBGndFGnd L2?{{BGnd null ne{BGnd aload !
+
+sgco BBox aload ! 2 ^ sub ~ 3 ^ sub ~ rf}if FGnd null ne{FGnd aload ! sgco}if}
+
+}{{}}? b/PaintProc{` SetBGndFGnd RepsH{Width Height F mx PaintData imagemask
+
+Width 0 +}repeat E}b E |/GDIBWPatternMx null |/pfprep{save 4 1 $
+
+/PatternOfTheDay 4 1 $ GDIBWPatternDict `/PaintData ~ |/BGnd ~ |/FGnd ~ | E
+
+CTMsave GDIBWPatternMx setmatrix GDIBWPatternDict matrix mp CTMrestore ~ !}b
+
+/hrf null |/prf{pfprep ~ 6 1 $ 5 hrf restore}b/GraphInit{GDIHMatrix null eq{
+
+/SavedCTM matrix | : ADO_mxRot concat 0 0 snap + : 0.48 @ GDIHPatternDict `
+
+YStep mul ~ XStep mul ~ dsnap YStep V ~ XStep V ~ E +S/GDIHMatrix matrix
+
+currentmatrix readonly | ; : 0.24 -0.24 +S GDIBWPatternDict ` Width Height E
+
+dsnap +S/GDIBWPatternMx matrix currentmatrix readonly | ; ;}if}b/cirp{360 0 An
+
+C}b/ellp{CTMsave + +S 0.5 0 M 0 0 0.5 360 0 An C CTMrestore}b/rrp{/rad ~ |/y2
+
+~ |/x2 ~ |/y1 ~ |/x1 ~ | x2 x1 add 2 V y1 M x1 y1 x1 y2 rad arct x1 y2 x2 y2
+
+rad arct x2 y2 x2 y1 rad arct x2 y1 x1 y1 rad arct C}b/RRp{CTMsave + +S/dyS ~
+
+|/dxS ~ | dxS 2 V 0 M 0 0 0 dyS 0.5 arct 0 dyS dxS dyS 0.5 arct dxS dyS dxS 0
+
+0.5 arct dxS 0 0 0 0.5 arct C CTMrestore}b
+
+
+
+L2? not g{/arct{arcto ! ! ! !}b/GDIpattfill{@ ` BGnd null ne PaintType 2 eq
+
+and{: BGnd aload ! sgco fEOFill{O}{L}? ; FGnd aload ! U/fGray 2 ^ put{2}{4}?
+
+-1 $}if E @ patterncalc : 4 ^/PaintType get 2 eq{fGray{6 -1 $ sg}{8 -3 $ sco}?
+
+}if fEOFill{eoclip}{clip}? N patternfill ; N}b/hrf{/fGray 1 ^ 6 eq | -4 $ N rp
+
+C/fEOFill F | GDIpattfill}b/hfMain{/fEOFill ~ |/fGray ~ | GDIpattfill}b/hf{T
+
+hfMain}b/hfW{F hfMain}b/hs{currentpoint strokepath M hfW}b/pfMain{/fEOFill ~ |
+
+pfprep GDIpattfill restore N}b/pf{T pfMain}b/pfW{F pfMain}b/ps{currentpoint
+
+strokepath M pfW}b/mpstr 1 string |/mp{~ @ length 12 add dict copy `
+
+/PatternCTM matrix currentmatrix |/PatternMatrix ~ |/PatWidth XStep mpstr
+
+length mul |/PatHeight YStep |/FontType 3 |/Encoding 256 array | 3 string 0 1
+
+255{Encoding ~ @ 3 ^ cvs cvn put}for !/FontMatrix matrix |/FontBBox BBox |
+
+/BuildChar{! @ ` XStep 0 FontBBox aload ! setcachedevice/PaintProc , E : exec
+
+;}b & E ~ @ 3 -1 $ definefont}b/patterncalc{` : PatternCTM setmatrix
+
+PatternMatrix concat BBox aload ! ! ! + pathbbox ; PatHeight V ceiling 4 1 $
+
+PatWidth V ceiling 4 1 $ PatHeight V floor 4 1 $ PatWidth V floor 4 1 $ 2 ^
+
+sub cvi abs ~ 3 ^ sub cvi abs ~ 4 2 $ PatHeight mul ~ PatWidth mul ~ E}b
+
+/patternfill{5 -1 $ @ ` Ji PatternCTM setmatrix PatternMatrix concat 0 2 ^ 2 ^
+
+M 0 1 mpstr length 1 sub{1 ^ mpstr 3 1 $ put}for ! 2 ^{currentpoint 5 ^{mpstr
+
+S}repeat YStep add M}repeat ! ! ! ! E}b}e
+
+
+
+L2? g{/mp/makepattern , |/hrf{6 eq setAorABC setpattern rectfill}b/hf{
+
+setAorABC setpattern O}b/hfW{setAorABC setpattern L}b/hs{setAorABC setpattern
+
+K}b/pf{pfprep setpattern O restore N}b/pfW{pfprep setpattern L restore N}b/ps{
+
+pfprep setpattern K restore N}b}e
+
+
+
+/iw 0 |/ih 0 |/im_save 0 |/s 0 |/polarity 0 |/smoothflag 0 |/mystring 0 |/bpc
+
+0 |/setup1asciiproc{[currentfile mystring/readhexstring cvx/! cvx]cvx bind}b
+
+/setup1binaryproc{[currentfile mystring/readstring cvx/! cvx]cvx bind}b
+
+/setup2asciiproc{currentfile/ASCII85Decode filter/RunLengthDecode filter}b
+
+/setup2binaryproc{currentfile/RunLengthDecode filter}b/mycolorspace{colspABC}|
+
+/myimagedict{/myimagedict 10 dict | myimagedict @ `/ImageType 1 |
+
+/MultipleDataSource F | E}b/imageprocarray[/setup1binaryproc/setup1asciiproc
+
+/setup2binaryproc/setup2asciiproc/setup1binarydecodeproc/setup1asciidecodeproc
+
+]|/L2Polarity{{[1 0]}{[0 1]}?}b/Q{/im_save save | imageprocarray ~ get/s ~ , |
+
+L2Polarity/polarity ~ |/smoothflag ~ | snap +/dx 2 ^ |/dy 1 ^ | +S/mystring ~
+
+string |/bpc ~ |/ih ~ |/iw ~ |}b/X{/im_save save | imageprocarray ~ get/s ~ ,
+
+| L2Polarity/polarity ~ |/smoothflag ~ | snap +/dx 2 ^ |/dy 1 ^ | +S/mystring
+
+~ string |/bpc ~ |/ih ~ |/iw ~ |}b/Z{im_save restore}b/Y{sgco myimagedict @ `
+
+/Width iw |/Height ih |/Decode polarity |/ImageMatrix[iw 0 0 ih 0 0]|
+
+/DataSource s |/BitsPerComponent 1 |/Interpolate smoothflag | E imagemask}b
+
+
+
+L2? not g{/setup2asciiproc{[/Level2ImagesError , aload ! T FatalErrorIf}b
+
+/setup2binaryproc/setup2asciiproc , |/L2Polarity{}|/Y{sgco iw ih polarity[iw 0
+
+0 ih 0 0]s imagemask}b}e
+
+
+
+L2? not g{/testsystemdict{where{systemdict eq{T}{F}?}{F}?}b/c 1 |/colorimage
+
+where{! T}{F}?{/c 0 statusdict `/processcolors where{! ! processcolors}{
+
+/deviceinfo where{! deviceinfo/Colors known{!{deviceinfo/Colors get}}if}if}? E
+
+| c 0 ne{/colorimage testsystemdict/setcolortransfer testsystemdict
+
+/currentcolortransfer testsystemdict/currentcmykcolor testsystemdict and and
+
+and not{/c 0 |}if}if}if c @ 1 ne ~ @ 3 ne ~ 4 ne and and{/c 0 |}if c 1 eq g{
+
+/expandbw{expandfactor mul round cvi bwclut ~ get 255 V}b/doclutimage{!/bwclut
+
+~ | bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/expandfactor ~ |[/expandbw ,/exec , @
+
+currenttransfer ~]cvx bind settransfer iw ih bpc[iw 0 0 ih 0 0]s image}b}e c @
+
+3 eq ~ 4 eq or g{/nullproc{{}}|/concatutil{/exec , 7 -1 $/exec ,}b/defsubclut{
+
+1 add getinterval |}b/spconcattransfer{/Dclut ~ |/Cclut ~ |/Bclut ~ |/Aclut ~
+
+|/ncompute ~ , | currentcolortransfer[{Aclut ncompute}concatutil]cvx[{Bclut
+
+ncompute}concatutil]cvx[{Cclut ncompute}concatutil]cvx[{Dclut ncompute}
+
+concatutil]cvx setcolortransfer}b/setuprgbcluts{/bit3x rgbclut length 3 sub |
+
+/bit1x bit3x 3 idiv |/rclut rgbclut |/gclut rclut 1 bit3x defsubclut/bclut
+
+rclut 2 bit3x defsubclut}b}e c 3 eq g{/3compute{~ bit3x mul round cvi get 255
+
+V}b/doclutimage{/rgbclut ~ | ! setuprgbcluts/3compute rclut gclut bclut @
+
+spconcattransfer iw ih bpc[iw 0 0 ih 0 0][s/exec ,/@ , @]cvx nullproc nullproc
+
+T 3 colorimage}b}e c 4 eq g{/ftoint{1 ~ sub 255 mul round cvi}b/stuffclut{
+
+cmykindex 3 -1 $ put}b/4compute{~ bit4x mul round cvi get 255 V}b
+
+/invalidcolortable? T |/computecmykclut{setuprgbcluts/bit4x rgbclut length 3
+
+idiv 4 mul 4 sub |/cmykclut bit4x 4 add string |/cclut cmykclut |/mclut cclut
+
+1 bit4x defsubclut/yclut cclut 2 bit4x defsubclut/kclut cclut 3 bit4x
+
+defsubclut/cmykindex 0 | 0 1 bit1x{@/cmykindex ~ bit1x ~ sub 4 mul | 3 mul @
+
+rclut ~ get 255 V ~ @ gclut ~ get 255 V ~ bclut ~ get 255 V setrgbcolor
+
+currentcmykcolor ftoint kclut stuffclut ftoint yclut stuffclut ftoint mclut
+
+stuffclut ftoint cclut stuffclut}for}b/doclutimage{/rgbclut ~ | !
+
+invalidcolortable?{computecmykclut}if/4compute cclut mclut yclut kclut
+
+spconcattransfer iw ih bpc[iw 0 0 ih 0 0][s/exec ,/@ , @ @]cvx nullproc
+
+nullproc nullproc T 4 colorimage}b}e c 0 eq g{/a{3 mul 3 getinterval
+
+putinterval ~ 3 add ~ 3 copy}b/8lookup/a , |/4lookup{/byte 1 ^ | -4 bitshift a
+
+byte 15 and a}b/2lookup{/byte 1 ^ | -6 bitshift a byte -4 bitshift 3 and a
+
+byte -2 bitshift 3 and a byte 3 and a}b/colorexpand{mystringexp 0 rgbclut 3
+
+copy 7 -1 $/mylookup , forall ! ! ! ! !}b/createexpandstr{/mystringexp ~
+
+mystring length mul string |}b/doclutimage{/rgbclut ~ | !/mylookup bpc 8 eq{3
+
+createexpandstr/8lookup}{bpc 4 eq{6 createexpandstr/4lookup}{12
+
+createexpandstr/2lookup}?}? , | iw ih bpc[iw 0 0 ih 0 0][s/exec ,/colorexpand
+
+,/exec ,]cvx F 3 colorimage}b}e/colorimage where{! T}{F}? g{/do24image{iw ih 8
+
+[iw 0 0 ih 0 0]s F 3 colorimage}b}DefIf_El{/rgbtogray{/str ~ |/len str length
+
+|/smlen len 3 idiv |/rstr str |/gstr str 1 len 1 sub getinterval |/bstr str 2
+
+len 2 sub getinterval | str @ 0 1 smlen 1 sub{@ 3 mul rstr 1 ^ get 0.3 mul
+
+gstr 2 ^ get 0.59 mul add bstr 3 -1 $ get 0.11 mul add round cvi put @}for ! 0
+
+smlen getinterval}b/do24image{iw ih 8[iw 0 0 ih 0 0][s/exec ,/rgbtogray ,/exec
+
+,]cvx bind image}b}e/doNimage{bpc 24 eq{do24image}{iw ih bpc[iw 0 0 ih 0 0]s
+
+image}?}b}e
+
+
+
+L2? g{/doclutimage{/rgbclut ~ | ! bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/hival ~ |[
+
+/Indexed colspABC hival rgbclut]setcolorspace myimagedict @ `/Width iw |
+
+/Height ih |/Decode[0 hival]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |
+
+/BitsPerComponent bpc |/Interpolate smoothflag | E image}b/doCMYKclutimage{
+
+/CMYKclut ~ | ! bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/hival ~ |[/Indexed/DeviceCMYK
+
+hival CMYKclut]setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode[0
+
+hival]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent bpc |
+
+/Interpolate smoothflag | E image}b/doNimage{bpc 24 eq{colspABC}{colspA}?
+
+setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode bpc 24 eq{[0 1 0 1
+
+0 1]}{[0 1]}? |/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent
+
+bpc 24 eq{8}{bpc}? |/Interpolate smoothflag | E image}b/doCMYKimage{
+
+/DeviceCMYK setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode[0 1 0
+
+1 0 1 0 1]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent 8 |
+
+/Interpolate smoothflag | E image}b}e
+
+
+
+/GreNewFont{10 dict @ 3 1 $ | @ ` 4 1 $/FontType 3 |/FontMatrix ~ |/FontBBox ~
+
+|/Encoding 256 array | 0 1 255{Encoding ~/.notdef put}for/CharProcs 257 dict |
+
+CharProcs/.notdef{}put/Metrics 257 dict | Metrics/.notdef 3 -1 $ put/BuildChar
+
+{/char ~ |/fontdict ~ |/charname fontdict/Encoding get char get | fontdict
+
+/Metrics get charname get aload ! setcachedevice fontdict ` Encoding char get
+
+CharProcs ~ get E exec}| E definefont !}|/AddChar{` Encoding 3 1 $ put
+
+CharProcs 3 1 $ put Metrics 3 1 $ put E}|
+
+
+
+/FEbuf 2 string |/FEglyph 3 string |/FE{(G00)FEglyph copy ! 1 ~{@ 16 lt{
+
+/offset 2 store}{/offset 1 store}? @ 16 FEbuf cvrs FEglyph ~ offset ~
+
+putinterval 1 ^ ~ FEglyph cvn put}for}bind |/Type1Hdr{11 dict `/FontName ~ |
+
+/PaintType ~ |/FontType 1 |/FontMatrix[1 3 ^ V 0 0 1 6 ^ V 0 0]| !/Encoding
+
+256 array 0 1 255{1 ^ ~/.notdef put}for 3 ^ 3 ^ FE | ! !/FontBBox{0 0 0 0}| &
+
+E currentfile eexec}bind |
+
+
+/pp 1 string |/ss 1 string |/rledecodebinary{/DC 0 |/BC 0 |{DC mystring length
+
+ge{exit}if currentfile ss readstring ! 0 get/BC ~ | BC 127 le{/BC BC 1 add |
+
+DC 1 DC BC add 1 sub{mystring ~ currentfile ss readstring ! 0 get put}for}{/BC
+
+257 BC sub | currentfile ss readstring ! 0 get/pp ~ | DC 1 DC BC add 1 sub{
+
+mystring ~ pp put}for}?/DC DC BC add |}loop mystring}b/rledecodeascii{/DC 0 |
+
+/BC 0 |{DC mystring length ge{exit}if currentfile ss readhexstring ! 0 get/BC
+
+~ | BC 127 le{/BC BC 1 add | DC 1 DC BC add 1 sub{mystring ~ currentfile ss
+
+readhexstring ! 0 get put}for}{/BC 257 BC sub | currentfile ss readhexstring !
+
+0 get/pp ~ | DC 1 DC BC add 1 sub{mystring ~ pp put}for}?/DC DC BC add |}loop
+
+mystring}b/setup1asciidecodeproc{[/rledecodeascii cvx]cvx bind}b
+
+/setup1binarydecodeproc{[/rledecodebinary cvx]cvx bind}b
+
+
+userdict/Pscript_Win_Compat 13 dict dup begin/bd{bind def}bind def/ld{load def
+
+}bd/CB{pop pop pop pop}bind def/B{pop pop pop pop}bind def/$x matrix def/SS{
+
+/pagesave save def}bind def/RS{/pagesave where{pop pagesave restore}{$x matrix
+
+invertmatrix concat}ifelse}bind def/ANSIVec[0/grave 1/acute 2/circumflex 3
+
+/tilde 4/macron 5/breve 6/dotaccent 7/dieresis 8/ring 9/cedilla 10
+
+/hungarumlaut 11/ogonek 12/caron 13/dotlessi 39/quotesingle 96/grave 124/bar
+
+130/quotesinglbase 131/florin 132/quotedblbase 133/ellipsis 134/dagger 135
+
+/daggerdbl 136/circumflex 137/perthousand 138/Scaron 139/guilsinglleft 140/OE
+
+145/quoteleft 146/quoteright 147/quotedblleft 148/quotedblright 149/bullet 150
+
+/endash 151/emdash 152/tilde 153/trademark 154/scaron 155/guilsinglright 156
+
+/oe 159/Ydieresis 160/space 161/exclamdown 164/currency 165/yen 166/brokenbar
+
+167/section 168/dieresis 169/copyright 170/ordfeminine 171/guillemotleft 172
+
+/logicalnot 173/hyphen 174/registered 175/macron 176/degree 177/plusminus 178
+
+/twosuperior 179/threesuperior 180/acute 181/mu 182/paragraph 183
+
+/periodcentered 184/cedilla 185/onesuperior 186/ordmasculine 187
+
+/guillemotright 188/onequarter 189/onehalf 190/threequarters 191/questiondown
+
+192/Agrave 193/Aacute 194/Acircumflex 195/Atilde 196/Adieresis 197/Aring 198
+
+/AE 199/Ccedilla 200/Egrave 201/Eacute 202/Ecircumflex 203/Edieresis 204
+
+/Igrave 205/Iacute 206/Icircumflex 207/Idieresis 208/Eth 209/Ntilde 210/Ograve
+
+211/Oacute 212/Ocircumflex 213/Otilde 214/Odieresis 215/multiply 216/Oslash
+
+217/Ugrave 218/Uacute 219/Ucircumflex 220/Udieresis 221/Yacute 222/Thorn 223
+
+/germandbls 224/agrave 225/aacute 226/acircumflex 227/atilde 228/adieresis 229
+
+/aring 230/ae 231/ccedilla 232/egrave 233/eacute 234/ecircumflex 235/edieresis
+
+236/igrave 237/iacute 238/icircumflex 239/idieresis 240/eth 241/ntilde 242
+
+/ograve 243/oacute 244/ocircumflex 245/otilde 246/odieresis 247/divide 248
+
+/oslash 249/ugrave 250/uacute 251/ucircumflex 252/udieresis 253/yacute 254
+
+/thorn 255/ydieresis]def currentdict{dup type/operatortype eq{[exch]cvx def}{
+
+pop pop}ifelse}forall/initialize{currentdict exch begin begin}bind def
+
+/terminate{/@FL where not{pop end end}{pop}ifelse}bind def/suspend/terminate
+
+load def/resume/initialize load def/M/moveto load def end put/Courier findfont
+
+10 scalefont setfont
+
+
+end /ProcSet defineresource pop
+
+
+
+
+
+
+Pscript_Win_Compat dup /initialize get exec
+
+[ 0 1.000 -1.000 0 0 0 ] false /Pscript_Win_Driver /ProcSet findresource dup /initialize get exec
+
+
+
+
+
+/mysetup [ 0.240 0 0 -0.240 8.880 592.800 ] | 
+
+
+
+
+
+
+userdict begin /pagesave save def end mysetup concat colspRefresh : 1.000 1.000 1.000 sco 0 0 2550 3300 rf ; 
+
+
+
+
+
+
+114 70 N M 1 1 rr 
+
+114 70 N M 3000 2250 rr : 1.000 1.000 1.000 sco O ; 
+
+114 70 N M 1 1 rr 
+
+114 70 N M 1 1 rr 
+
+114 70 N M 2401 1026 rr : 0.800 1.000 0.800 sco O ; 1 Lw 0 Lc 0 Lj solid 0.800 1.000 0.800 sco K 
+
+234 176 N M 2131 295 rr : 114 70 3000 2250 rc 0.647 0 0.129 sco %%IncludeFont: Helvetica-Bold
+
+(F0) cvn
+
+0.960 
+
+ (Helvetica-Bold) cvn /Type1 
+
+T 
+
+(Helvetica-Bold) cvn
+
+mF 
+
+(F0_100) cvn
+
+F0
+
+100 
+
+xF 
+
+F0_100
+
+Ji 
+
+264 193 M 
+
+-0.100 0 (T)A 
+
+0.100 0 (r)A 
+
+0.400 0 (a)A 
+
+-0.100 0 (d)A 
+
+-0.800 0 (i)A 
+
+0.700 0 (t)A 
+
+-0.800 0 (i)A 
+
+-0.100 0 (on)A 
+
+0.400 0 (a)A 
+
+1.000 0 32 -0.800 0 (l )D 
+
+-0.100 0 (p)A 
+
+0.400 0 (a)A 
+
+0.100 0 (r)A 
+
+-0.300 0 (t)A 
+
+0.200 0 (i)A 
+
+-0.300 0 (t)A 
+
+0.200 0 (i)A 
+
+-0.100 0 (o)A 
+
+-1.100 0 (n)A 
+
+0.200 0 (i)A 
+
+0.300 0 32 -0.100 0 (ng )D 
+
+-0.600 0 (a)A 
+
+0.200 0 (l)A 
+
+-0.100 0 (go)A 
+
+0.100 0 (r)A 
+
+-0.800 0 (i)A 
+
+0.700 0 (t)A 
+
+-0.100 0 (h)A 
+
+0.100 0 (m)A 
+
+0.800 0 32 -0.600 0 (s )D 
+
+0.400 0 (c)A 
+
+-0.100 0 (o)A 
+
+0.100 0 (m)A 
+
+-0.100 0 (pu)A 
+
+-0.300 0 (t)A 
+
+0.400 0 (e)A 
+
+; : 114 70 3000 2250 rc 0.647 0 0.129 sco F0_100
+
+Ji 
+
+339 336 M 
+
+-1.200 0 32 0.400 0 (a )D 
+
+-0.100 0 (p)A 
+
+0.400 0 (a)A 
+
+0.100 0 (r)A 
+
+-0.300 0 (t)A 
+
+0.200 0 (i)A 
+
+-0.300 0 (t)A 
+
+0.200 0 (i)A 
+
+-0.700 0 32 -0.100 0 (on d)D 
+
+0.200 0 (i)A 
+
+0.100 0 (r)A 
+
+0.400 0 (e)A 
+
+-0.600 0 (c)A 
+
+0.700 0 (t)A 
+
+-0.800 0 (l)A 
+
+-0.200 0 32 0.400 0 (y )D 
+
+-0.700 0 32 -0.100 0 (on )D 
+
+-0.300 0 (t)A 
+
+-0.100 0 (h)A 
+
+-0.200 0 32 0.400 0 (e )D 
+
+-0.100 0 (o)A 
+
+0.100 0 (r)A 
+
+-0.800 0 (i)A 
+
+-0.100 0 (g)A 
+
+0.200 0 (i)A 
+
+-0.100 0 (n)A 
+
+0.400 0 (a)A 
+
+1.000 0 32 -0.800 0 (l )D 
+
+-0.100 0 (g)A 
+
+0.100 0 (r)A 
+
+-0.600 0 (a)A 
+
+-0.100 0 (ph)A 
+
+0.700 0 (!)A 
+
+; 
+
+428 664 N M -7 1 - -9 0 - -20 1 - -22 1 - -23 1 - -23 3 - -21 5 - -9 3 - -8 5 - -7 5 - -6 6 - -4 8 - -4 8 - -3 11 - -2 11 - -2 25 - 0 26 - 2 27 - 3 27 - 5 23 - 2 11 - 3 9 - 7 17 - 9 15 - 11 14 - 12 13 - 13 10 - 14 10 - 13 8 - 14 6 - 14 5 - 16 4 - 17 2 - 17 1 - 17 -1 - 16 -2 - 14 -4 - 13 -5 - 6 -3 - 5 -5 - 9 -11 - 8 -13 - 7 -14 - 6 -14 - 7 -14 - 7 -11 - 3 -4 - 4 -4 - 7 -4 - 7 -2 - 5 -1 - 6 1 - 7 2 - 8 2 - 10 1 - 12 1 - 15 0 - 18 -1 - 20 -2 - 21 -1 - 21 0 - 21 0 - 21 1 - 18 3 - 9 3 - 9 4 - 17 10 - 17 12 - 16 12 - 16 11 - 7 5 - 7 4 - 7 2 - 7 1 - 6 0 - 6 -2 - 6 -4 - 6 -5 - 5 -7 - 6 -9 - 5 -9 - 5 -11 - 10 -22 - 8 -24 - 6 -24 - 4 -22 - 1 -9 - 0 -9 - -1 -14 - -4 -13 - -5 -12 - -7 -11 - -10 -11 - -10 -10 - -12 -11 - -13 -11 - -14 -12 - -17 -14 - -17 -14 - -20 -14 - -20 -13 - -22 -11 - -22 -9 - -23 -6 - -12 -1 - -13 -1 - -29 1 - -31 4 - -31 5 - -31 6 - -27 7 - -13 3 - -11 2 - -10 3 - -9 2 - -7 2 - -5 2 - -5 3 - -3 2 - -4 4 - -1 5 - 0 4 - 0 4 - -2 3 - -4 2 - -5 1 - -6 0 - -12 -1 - -7 -1 - -9 0 - -11 0 - -12 1 - C : 0.502 0.502 0.502 sco O ; 
+
+420 656 N M -7 1 - -9 0 - -20 1 - -22 1 - -23 1 - -23 3 - -21 5 - -9 3 - -8 5 - -7 5 - -6 6 - -4 8 - -4 8 - -3 11 - -2 11 - -3 24 - 0 27 - 2 27 - 4 26 - 4 24 - 3 11 - 3 9 - 7 17 - 9 15 - 11 13 - 12 13 - 13 11 - 13 9 - 14 8 - 14 7 - 14 5 - 16 3 - 17 3 - 17 0 - 17 0 - 16 -3 - 14 -3 - 13 -5 - 6 -3 - 5 -5 - 9 -11 - 8 -13 - 7 -15 - 6 -14 - 7 -13 - 7 -11 - 3 -5 - 4 -3 - 7 -5 - 6 -2 - 6 0 - 6 1 - 7 2 - 8 2 - 10 1 - 12 1 - 15 0 - 18 -1 - 20 -2 - 20 -1 - 22 0 - 21 0 - 20 1 - 19 3 - 9 3 - 8 3 - 17 10 - 17 12 - 17 12 - 15 12 - 8 4 - 7 4 - 7 3 - 7 1 - 6 0 - 6 -2 - 6 -4 - 6 -6 - 5 -7 - 6 -8 - 5 -10 - 5 -10 - 10 -23 - 8 -24 - 6 -24 - 4 -21 - 1 -10 - 0 -8 - -1 -14 - -4 -13 - -5 -12 - -7 -11 - -10 -11 - -10 -10 - -12 -11 - -13 -11 - -14 -12 - -17 -14 - -17 -14 - -20 -14 - -20 -13 - -22 -12 - -22 -8 - -23 -6 - -12 -1 - -13 -1 - -29 1 - -31 4 - -31 5 - -31 6 - -27 7 - -13 3 - -11 2 - -10 3 - -9 2 - -7 2 - -6 2 - -4 2 - -3 2 - -4 5 - -2 4 - 0 5 - 0 3 - -1 4 - -4 2 - -6 1 - -5 0 - -12 -1 - -8 -1 - -8 0 - -11 0 - -12 1 - C : 0.200 0.200 0.800 sco O ; 
+
+1820 653 N M -7 1 - -9 0 - -20 1 - -22 1 - -23 1 - -23 3 - -21 5 - -9 4 - -8 4 - -7 6 - -6 6 - -4 8 - -4 9 - -3 11 - -2 11 - -2 26 - 0 27 - 2 28 - 3 28 - 5 24 - 2 11 - 3 10 - 7 17 - 9 16 - 11 14 - 12 13 - 13 11 - 14 10 - 13 8 - 14 7 - 15 5 - 16 4 - 16 2 - 17 1 - 17 -1 - 16 -2 - 14 -4 - 13 -5 - 6 -4 - 5 -4 - 9 -11 - 8 -14 - 7 -15 - 7 -15 - 6 -13 - 7 -12 - 3 -4 - 4 -4 - 7 -5 - 7 -2 - 5 0 - 6 1 - 7 2 - 8 2 - 10 1 - 12 1 - 15 0 - 18 -2 - 20 -1 - 21 -1 - 22 -1 - 21 0 - 20 2 - 18 3 - 9 3 - 9 3 - 17 11 - 17 12 - 16 13 - 16 11 - 7 5 - 7 4 - 7 3 - 7 1 - 6 0 - 6 -2 - 6 -4 - 6 -6 - 5 -7 - 6 -9 - 5 -10 - 5 -11 - 10 -23 - 8 -25 - 6 -25 - 4 -22 - 1 -10 - 0 -9 - -1 -15 - -3 -13 - -6 -12 - -7 -12 - -9 -11 - -11 -10 - -12 -11 - -13 -12 - -14 -13 - -17 -14 - -17 -15 - -20 -14 - -20 -13 - -22 -12 - -22 -9 - -23 -6 - -12 -2 - -13 0 - -29 1 - -31 3 - -31 6 - -30 6 - -28 7 - -13 3 - -11 3 - -10 3 - -9 2 - -7 2 - -5 2 - -5 3 - -3 2 - -4 5 - -1 4 - 0 5 - 0 3 - -2 4 - -4 2 - -5 1 - -6 0 - -5 0 - -7 -1 - -7 -1 - -9 0 - -10 0 - -13 1 - C : 0.502 0.502 0.502 sco O ; 
+
+1812 645 N M -7 1 - -9 0 - -20 1 - -22 0 - -23 2 - -23 3 - -21 5 - -9 3 - -8 5 - -7 5 - -6 7 - -4 8 - -4 9 - -3 10 - -2 12 - -2 25 - 0 28 - 2 28 - 3 27 - 2 13 - 3 12 - 2 10 - 3 10 - 7 17 - 9 16 - 11 14 - 12 13 - 13 11 - 14 10 - 13 8 - 14 7 - 14 5 - 16 4 - 17 2 - 17 1 - 17 -1 - 16 -2 - 14 -4 - 13 -5 - 6 -4 - 5 -4 - 9 -11 - 8 -14 - 7 -15 - 6 -15 - 7 -13 - 7 -12 - 3 -4 - 4 -4 - 7 -5 - 7 -2 - 5 0 - 6 1 - 7 2 - 8 2 - 10 1 - 12 1 - 15 0 - 18 -1 - 20 -2 - 21 -1 - 21 0 - 21 0 - 21 1 - 18 3 - 9 3 - 9 4 - 17 10 - 17 12 - 16 13 - 16 12 - 7 4 - 7 4 - 7 3 - 7 1 - 6 0 - 6 -2 - 6 -4 - 6 -6 - 5 -7 - 6 -9 - 5 -10 - 5 -10 - 10 -24 - 8 -25 - 6 -24 - 4 -22 - 1 -10 - 0 -9 - -1 -15 - -4 -14 - -5 -12 - -7 -11 - -10 -11 - -10 -11 - -12 -10 - -13 -12 - -14 -13 - -17 -14 - -17 -15 - -20 -14 - -20 -14 - -22 -11 - -22 -9 - -11 -4 - -12 -2 - -12 -2 - -13 0 - -29 1 - -31 3 - -31 6 - -31 6 - -27 7 - -13 3 - -11 3 - -10 3 - -9 2 - -7 2 - -5 2 - -5 2 - -3 2 - -4 5 - -1 5 - 0 4 - 0 4 - -2 3 - -4 3 - -5 1 - -6 0 - -12 -1 - -7 -1 - -9 -1 - -11 1 - -12 1 - C : 0.200 0.200 0.800 sco O ; 
+
+N 1929 615.500 M 2 1 rr : 0 0 0 sco O ; 
+
+N 1928 616.500 M 4 1 rr : 0 0 0 sco O ; 
+
+N 1927 617.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1926 618.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1927 619.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1928 620.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1929 621.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1930 622.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1931 623.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1931 624.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1932 625.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1933 626.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1934 627.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1935 628.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1936 629.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1937 630.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1938 631.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1940 632.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1941 633.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1942 634.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1943 635.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1944 636.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1945 637.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1946 638.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1947 639.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1948 640.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1948 641.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1949 642.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1950 643.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1951 644.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1952 645.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1953 646.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1954 647.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1955 648.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1955 649.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1956 650.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1957 651.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1958 652.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1959 653.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1960 654.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1960 655.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1961 656.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1962 657.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1963 658.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1963 659.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1964 660.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1965 661.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1966 662.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1966 663.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1967 664.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1968 665.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1969 666.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1969 667.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1971 668.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1971 669.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1972 670.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1972 671.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1973 672.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1973 673.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1974 674.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1974 675.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1974 676.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1975 677.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1975 678.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1976 679.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1976 680.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1977 681.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1977 682.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1978 683.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1978 684.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1979 685.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1979 686.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1980 687.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1980 688.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1981 689.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1981 690.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1982 691.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1982 692.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1983 693.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1983 694.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1983 695.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1984 696.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1984 697.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1985 698.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1985 699.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1986 700.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1986 701.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1987 702.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1987 703.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1987 704.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1988 705.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1988 706.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1989 707.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1989 708.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1990 709.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1990 710.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1990 711.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1991 712.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1991 713.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1992 714.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1992 715.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1993 716.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1993 717.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1994 718.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1994 719.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1995 720.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1995 721.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1996 722.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1996 723.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1997 724.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1997 725.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1998 726.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1998 727.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1999 728.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1999 729.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2000 730.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2000 731.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2001 732.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2001 733.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2001 734.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2002 735.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2002 736.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2003 737.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2003 738.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2004 739.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2004 740.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2005 741.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2005 742.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2006 743.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2006 744.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2007 745.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2007 746.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2008 747.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2008 748.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2009 749.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2010 750.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2010 751.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2011 752.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2011 753.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2012 754.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2013 755.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2013 756.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 2014 757.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2015 758.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2016 759.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2016 760.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2017 761.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2018 762.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2019 763.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2020 764.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 2022 765.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2023 766.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2024 767.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 2025 768.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 2027 769.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2028 770.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 2029 771.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 2031 772.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 2032 773.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 2033 774.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 2035 775.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 2036 776.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 2038 777.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2039 778.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 2040 779.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 2042 780.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2043 781.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2044 782.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 2046 783.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2047 784.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2047 785.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2048 786.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2049 787.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2049 788.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2050 789.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2051 790.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2051 791.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2052 792.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2052 793.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2053 794.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2053 795.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2053 796.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2053 797.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2054 798.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2054 799.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2054 800.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2054 801.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2055 802.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 803.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 804.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 805.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 806.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 807.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 808.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 809.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2056 810.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 811.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 812.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 813.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 814.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 815.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 816.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 817.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 818.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 819.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 820.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 821.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 822.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 823.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 824.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 825.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 826.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 827.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 828.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 829.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 830.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 831.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 832.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 833.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2055 834.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 835.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 836.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 837.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 838.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 839.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 840.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 841.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 842.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 843.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 844.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 845.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 846.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 847.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 848.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 849.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 850.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 851.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 852.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 853.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 854.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 855.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 856.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2054 857.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2054 858.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2054 859.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2054 860.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2054 861.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2054 862.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2054 863.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2054 864.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2054 865.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2054 866.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2054 867.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2053 868.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2053 869.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2053 870.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2053 871.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2053 872.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2053 873.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2053 874.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2053 875.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2053 876.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2053 877.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2053 878.500 M 6 1 rr : 0 0 0 sco O ; 
+
+1394 762 N M 0 22 - -257 0 - 0 46 - 257 0 - 0 23 - 86 -46 - -86 -45 - C : 0.502 0.502 0.502 sco O ; 
+
+1386 753 N M 0 23 - -257 0 - 0 46 - 257 0 - 0 22 - 85 -45 - -85 -46 - C : 0 0.800 0.600 sco O ; 
+
+LH 
+
+pagesave restore
+
+
+
+
+
+
+
+/Pscript_Win_Driver /ProcSet findresource dup /terminate get exec
+
+Pscript_Win_Compat dup /terminate get exec
+
+
+
+restore gr
+%
+% End Imported PIC File: slide7.eps
+%
+% Polyline
+%
+% Begin Imported EPS File: slide8.eps
+%
+n gs
+9900 389 tr
+15.269291 -15.269767 sc
+0 -430 tr
+-35 -150 tr
+save
+/showpage {} def
+% EPS file follows:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/defineresource where{pop}{userdict begin/defineresource{userdict/Resources 2
+
+copy known{get begin}{15 dict dup begin put}ifelse exch readonly exch
+
+currentdict 1 index known not{dup 30 dict def}if load 3 -1 roll 2 index put
+
+end}bind readonly def/findresource{userdict/Resources get exch get exch get}
+
+bind readonly def/resourceforall{pop pop pop pop}bind readonly def
+
+/resourcestatus{userdict/Resources 2 copy known{get exch 2 copy known{get exch
+
+known{0 -1 true}{pop pop false}ifelse}{pop pop pop false}ifelse}{pop pop false
+
+}ifelse}bind readonly def end}ifelse
+
+
+
+/Pscript_Win_Driver 200 dict dup begin
+
+
+/FatalErrorIf{{initgraphics findfont exch scalefont setfont counttomark 3 div
+
+cvi{moveto show}repeat showpage quit}{cleartomark}ifelse}bind def
+
+
+/VM? {vmstatus exch sub exch pop gt { [
+
+(This job requires more memory than is available in this printer.) 100 500
+
+(Try one or more of the following, and then print again:) 100 485
+
+(In the PostScript dialog box, click Optimize For Portability.) 115 470
+
+(In the Device Options dialog box, make sure the Available Printer Memory is accurate.) 115 455
+
+(Reduce the number of fonts in the document.) 115 440
+
+(Print the document in parts.) 115 425
+
+12 /Times-Roman showpage
+
+(%%[ PrinterError: Low Printer VM ]%%) =
+
+true FatalErrorIf}if} bind def
+
+
+/|/def load def/,/load load |/~/exch , |/?/ifelse , |/!/pop , |/`/begin , |/^
+
+/index , |/@/dup , |/+/translate , |/$/roll , |/U/userdict , |/M/moveto , |/-
+
+/rlineto , |/&/currentdict , |/:/gsave , |/;/grestore , |/F/false , |/T/true ,
+
+|/N/newpath , |/E/end , |/Ac/arc , |/An/arcn , |/A/ashow , |/D/awidthshow , |
+
+/C/closepath , |/V/div , |/O/eofill , |/L/fill , |/I/lineto , |/-C/rcurveto ,
+
+|/-M/rmoveto , |/+S/scale , |/Ji/setfont , |/Lc/setlinecap , |/Lj/setlinejoin
+
+, |/Lw/setlinewidth , |/S/show , |/LH/showpage , |/K/stroke , |/W/widthshow ,
+
+|/R/rotate , |/b{bind |}bind |/bd{bind |}bind |/xd{~ |}bd/ld{, |}bd/lw/Lw ld
+
+/lc/Lc ld/lj/Lj ld/sg/setgray ld/L2? F/languagelevel where{! languagelevel 2
+
+ge{! T}if}if |/g{@ not{U/DefIf_save save put}if U/DefIf_bool 2 ^ put}b
+
+/DefIf_El{if U/DefIf_bool get not @{U/DefIf_save get restore}if}b/e{DefIf_El !
+
+}b/self & |/reinitialize{[/TextInit/GraphInit/UtilsInit counttomark{@ where{
+
+self eq}{F}?{cvx exec}{!}?}repeat cleartomark}b/initialize{`{/ADO_mxRot ~ |
+
+/TextInitialised? F | reinitialize E}{U/Pscript_Win_Data 200 dict @ ` put
+
+/ADO_mxRot ~ |/TextInitialised? F | reinitialize}?}b/terminate{!{& self eq{
+
+exit}{E}?}loop E}b/suspend/terminate , |/resume{` Pscript_Win_Data `}b/snap{
+
+transform 0.25 sub round 0.25 add ~ 0.25 sub round 0.25 add ~ itransform}b
+
+/dsnap{dtransform round ~ round ~ idtransform}b<04>cvn{}|/setjn{{statusdict
+
+/jobname known{statusdict/jobname 3 -1 $ put}if}stopped cleartomark}b/solid{[]
+
+0 setdash}b/setdsh{0 setdash}b/colspRefresh{}b/rp{4 2 $ M 1 ^ 0 - 0 ~ - neg 0
+
+-}b/rr{1 ^ 0 - 0 ~ - neg 0 - C}b
+
+
+
+L2? not g{/rf{N rp L}b/fx{1 1 dtransform @ 0 ge{1 sub 1}{1 add -0.25}? 3 -1 $
+
+@ 0 ge{1 sub 1}{1 add -0.25}? 3 1 $ 4 1 $ idtransform 4 -2 $ idtransform}b/BZ{
+
+4 -2 $ snap + +S fx rf}b/rs{N rp C K}b/rc{N rp clip N}b/sg{setgray}b/sco{
+
+setrgbcolor}b/sgco{{sg}{sco}?}b}e
+
+
+
+L2? g{/colspA/DeviceGray |/colspABC/DeviceRGB |/setAorABC{{colspA}{colspABC}?
+
+setcolorspace}b/rf/rectfill , |/fx{1 1 dtransform @ 0 ge{1 sub 0.5}{1 add -0.5
+
+}? 3 -1 $ @ 0 ge{1 sub 0.5}{1 add -0.5}? 3 1 $ 4 1 $ idtransform 4 -2 $
+
+idtransform}b/BZ{4 -2 $ snap + +S fx rf}b/rs/rectstroke , |/rc/rectclip , |/sg
+
+{@ @ setcolor}b/sco{setcolor}b/colspRefresh{colspABC setcolorspace}b/sgco{{sg
+
+}{sco}?}b/UtilsInit{F setglobal}b/definecolorrendering{/ColorRendering
+
+defineresource !}b/findcolorrendering{@/ColorRendering resourcestatus{! !
+
+/ColorRendering findresource T}{! F}?}b/selectcolorrendering{@/ColorRendering
+
+resourcestatus{! !/ColorRendering}{!/DefaultColorRendering/ColorRendering}?
+
+findresource setcolorrendering}b}e
+
+
+
+/bullets{{/bullet}repeat}b/ANSIEncoding[/grave/acute/circumflex/tilde/macron
+
+/breve/dotaccent/dieresis/ring/cedilla/hungarumlaut/ogonek/caron/dotlessi 18
+
+bullets StandardEncoding 32 95 getinterval aload ! 3 bullets/quotesinglbase
+
+/florin/quotedblbase/ellipsis/dagger/daggerdbl/circumflex/perthousand/Scaron
+
+/guilsinglleft/OE 4 bullets/quoteleft/quoteright/quotedblleft/quotedblright
+
+/bullet/endash/emdash/tilde/trademark/scaron/guilsinglright/oe 2 bullets
+
+/Ydieresis/space/exclamdown/cent/sterling/currency/yen/brokenbar/section
+
+/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered
+
+/macron/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph
+
+/periodcentered/cedilla/onesuperior/ordmasculine/guillemotright/onequarter
+
+/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis
+
+/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute
+
+/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
+
+/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
+
+/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute
+
+/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve
+
+/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex
+
+/udieresis/yacute/thorn/ydieresis]| ANSIEncoding @ 39/quotesingle put 96/grave
+
+put/ANSIEncodingOld ANSIEncoding 256 array copy | ANSIEncodingOld @[138 153
+
+154 169 172 174 177 178 179 181 185 188 189 190 208 215 221 222 240 247 253
+
+254]{/bullet put @}forall 166/bar put 176/ring put
+
+
+
+/TextInit{TextInitialised? not{/Pscript_Windows_Font & |/TextInitialised? T |
+
+/fM[1 0 0 -1 0 0]|/mFM matrix |/iMat[1 0 0.212557 neg 1 0 0]|}if}b/xUP null |
+
+/yUP null |/uW null |/xSP null |/ySP null |/sW null |/copyfont{1 ^ length add
+
+dict `{1 ^/FID ne{|}{! !}?}forall & E}b/rF{3 copyfont @ `/Encoding
+
+ANSIEncoding &/CharStrings known{CharStrings/Eth known not{! ANSIEncodingOld}
+
+if}if | E}b/mF{findfont ~{@/Encoding get @ StandardEncoding eq{! T}{{
+
+ISOLatin1Encoding}stopped{! F}{eq}?{T}{@ ` T 32 1 127{Encoding 1 ^ get
+
+StandardEncoding 3 -1 $ get eq and}for E}?}?}{F}?{rF}{3 copyfont}? `
+
+/OrigFontType ~ |/OrigFontName ~ | & E 2 ^ ~ definefont fM 5 4 -1 $ put fM 4 0
+
+put fM makefont Pscript_Windows_Font 3 1 $ put}b/xF{scalefont
+
+Pscript_Windows_Font 3 1 $ put}b/xMF{mFM astore makefont Pscript_Windows_Font
+
+3 1 $ put}b/xF2/scalefont , |/xMF2{mFM astore makefont}b/sLT{: Lw -M
+
+currentpoint snap M 0 - 0 Lc K ;}b/sSU{N/uW ~ |/yUP ~ |/xUP ~ |}b/sU{xUP yUP
+
+uW sLT}b/sST{N/sW ~ |/ySP ~ |/xSP ~ |}b/sT{xSP ySP sW sLT}b/sR{: + R 0 0 M}b
+
+/sRxy{: matrix astore concat 0 0 M}b/eR/; , |
+
+
+
+/mBF{@ 4 copyfont `/FontName ~ |/OrigFontType ~ |/OrigFontName ~ | 0
+
+FontMatrix idtransform ! &/PaintType known{PaintType 0 eq{/PaintType 2 |
+
+/StrokeWidth ~ |}{PaintType 1 eq PaintType 2 eq or PaintType 3 eq or &
+
+/StrokeWidth known and{StrokeWidth add/StrokeWidth ~ |}{!}?}?}{!}? @ & E
+
+definefont Pscript_Windows_Font 3 1 $ put}b/xBF{Pscript_Windows_Font ` 1 ^
+
+/FontName get 1 ^ scalefont 3 1 $ scalefont 2 copy ~ | ~ ! | E}b/xMBF{mFM
+
+astore Pscript_Windows_Font ` 1 ^/FontName get 1 ^ makefont 3 1 $ makefont 2
+
+copy ~ | ~ ! | E}b/xBF2{/sB0 ~ mBF/sB1 sB0 3 -1 $ xBF sB1}b/xMBF2{/sB0 ~ mBF
+
+mFM astore/sB1 sB0 3 -1 $ xMBF sB1}b/sB{: Pscript_Windows_Font currentfont get
+
+Ji @ S ; S}b/asB{: Pscript_Windows_Font currentfont get Ji 3 copy A ; A}b/wsB{
+
+: Pscript_Windows_Font currentfont get Ji 4 copy W ; W}b/awsB{:
+
+Pscript_Windows_Font currentfont get Ji 6 copy D ; D}b/sBT3{: @ S ; 1 1 -M S}b
+
+/asBT3{: 3 copy A ; 1 1 -M A}b/wsBT3{: 4 copy W ; 1 1 -M W}b/awsBT3{: 6 copy D
+
+; 1 1 -M D}b/mIF{iMat 4 3 -1 $ put 2 copyfont `/OrigFontType ~ |/OrigFontName
+
+~ | @ & E definefont iMat makefont Pscript_Windows_Font 3 1 $ put}b
+
+
+
+/SavedCTM null |/CTMsave{/SavedCTM SavedCTM currentmatrix |}b/CTMrestore{
+
+SavedCTM setmatrix}b/mp null |/ADO_mxRot null |/GDIHMatrix null |
+
+/GDIHPatternDict 22 dict | GDIHPatternDict `/PatternType 1 |/PaintType 2 |
+
+/Reps L2?{1}{5}? |/XStep 8 Reps mul |/YStep XStep |/BBox[0 0 XStep YStep]|
+
+/TilingType 1 |/PaintProc{` 1 Lw[]0 setdash PaintData , exec E}b/FGnd null |
+
+/BGnd null |/HS_Horizontal{horiz}b/HS_Vertical{vert}b/HS_FDiagonal{fdiag}b
+
+/HS_BDiagonal{biag}b/HS_Cross{horiz vert}b/HS_DiagCross{fdiag biag}b/MaxXYStep
+
+XStep YStep gt{XStep}{YStep}? |/horiz{Reps{0 4 M XStep 0 - 0 8 +}repeat 0 -8
+
+Reps mul + K}b/vert{Reps{4 0 M 0 YStep - 8 0 +}repeat 0 -8 Reps mul + K}b/biag
+
+{Reps{0 0 M MaxXYStep @ - 0 YStep neg M MaxXYStep @ - 0 8 +}repeat 0 -8 Reps
+
+mul + 0 YStep M 8 8 - K}b/fdiag{Reps{0 0 M MaxXYStep @ neg - 0 YStep M
+
+MaxXYStep @ neg - 0 8 +}repeat 0 -8 Reps mul + MaxXYStep @ M 8 -8 - K}b E
+
+/makehatch{GDIHPatternDict/PaintData 3 -1 $ put CTMsave GDIHMatrix setmatrix
+
+GDIHPatternDict matrix mp CTMrestore ~ U ~ 2 ^ put}b/h0{/h0/HS_Horizontal
+
+makehatch}b/h1{/h1/HS_Vertical makehatch}b/h2{/h2/HS_FDiagonal makehatch}b/h3{
+
+/h3/HS_BDiagonal makehatch}b/h4{/h4/HS_Cross makehatch}b/h5{/h5/HS_DiagCross
+
+makehatch}b/GDIBWPatternDict 17 dict @ `/PatternType 1 |/PaintType L2?{1}{2}?
+
+|/RepsV L2?{1}{6}? |/RepsH L2?{1}{5}? |/BBox[0 0 RepsH 1]|/TilingType 1 |
+
+/XStep 1 |/YStep 1 |/Height 8 RepsV mul |/Width 8 |/mx[Width 0 0 Height neg 0
+
+Height]|/FGnd null |/BGnd null |/SetBGndFGnd L2?{{BGnd null ne{BGnd aload !
+
+sgco BBox aload ! 2 ^ sub ~ 3 ^ sub ~ rf}if FGnd null ne{FGnd aload ! sgco}if}
+
+}{{}}? b/PaintProc{` SetBGndFGnd RepsH{Width Height F mx PaintData imagemask
+
+Width 0 +}repeat E}b E |/GDIBWPatternMx null |/pfprep{save 4 1 $
+
+/PatternOfTheDay 4 1 $ GDIBWPatternDict `/PaintData ~ |/BGnd ~ |/FGnd ~ | E
+
+CTMsave GDIBWPatternMx setmatrix GDIBWPatternDict matrix mp CTMrestore ~ !}b
+
+/hrf null |/prf{pfprep ~ 6 1 $ 5 hrf restore}b/GraphInit{GDIHMatrix null eq{
+
+/SavedCTM matrix | : ADO_mxRot concat 0 0 snap + : 0.48 @ GDIHPatternDict `
+
+YStep mul ~ XStep mul ~ dsnap YStep V ~ XStep V ~ E +S/GDIHMatrix matrix
+
+currentmatrix readonly | ; : 0.24 -0.24 +S GDIBWPatternDict ` Width Height E
+
+dsnap +S/GDIBWPatternMx matrix currentmatrix readonly | ; ;}if}b/cirp{360 0 An
+
+C}b/ellp{CTMsave + +S 0.5 0 M 0 0 0.5 360 0 An C CTMrestore}b/rrp{/rad ~ |/y2
+
+~ |/x2 ~ |/y1 ~ |/x1 ~ | x2 x1 add 2 V y1 M x1 y1 x1 y2 rad arct x1 y2 x2 y2
+
+rad arct x2 y2 x2 y1 rad arct x2 y1 x1 y1 rad arct C}b/RRp{CTMsave + +S/dyS ~
+
+|/dxS ~ | dxS 2 V 0 M 0 0 0 dyS 0.5 arct 0 dyS dxS dyS 0.5 arct dxS dyS dxS 0
+
+0.5 arct dxS 0 0 0 0.5 arct C CTMrestore}b
+
+
+
+L2? not g{/arct{arcto ! ! ! !}b/GDIpattfill{@ ` BGnd null ne PaintType 2 eq
+
+and{: BGnd aload ! sgco fEOFill{O}{L}? ; FGnd aload ! U/fGray 2 ^ put{2}{4}?
+
+-1 $}if E @ patterncalc : 4 ^/PaintType get 2 eq{fGray{6 -1 $ sg}{8 -3 $ sco}?
+
+}if fEOFill{eoclip}{clip}? N patternfill ; N}b/hrf{/fGray 1 ^ 6 eq | -4 $ N rp
+
+C/fEOFill F | GDIpattfill}b/hfMain{/fEOFill ~ |/fGray ~ | GDIpattfill}b/hf{T
+
+hfMain}b/hfW{F hfMain}b/hs{currentpoint strokepath M hfW}b/pfMain{/fEOFill ~ |
+
+pfprep GDIpattfill restore N}b/pf{T pfMain}b/pfW{F pfMain}b/ps{currentpoint
+
+strokepath M pfW}b/mpstr 1 string |/mp{~ @ length 12 add dict copy `
+
+/PatternCTM matrix currentmatrix |/PatternMatrix ~ |/PatWidth XStep mpstr
+
+length mul |/PatHeight YStep |/FontType 3 |/Encoding 256 array | 3 string 0 1
+
+255{Encoding ~ @ 3 ^ cvs cvn put}for !/FontMatrix matrix |/FontBBox BBox |
+
+/BuildChar{! @ ` XStep 0 FontBBox aload ! setcachedevice/PaintProc , E : exec
+
+;}b & E ~ @ 3 -1 $ definefont}b/patterncalc{` : PatternCTM setmatrix
+
+PatternMatrix concat BBox aload ! ! ! + pathbbox ; PatHeight V ceiling 4 1 $
+
+PatWidth V ceiling 4 1 $ PatHeight V floor 4 1 $ PatWidth V floor 4 1 $ 2 ^
+
+sub cvi abs ~ 3 ^ sub cvi abs ~ 4 2 $ PatHeight mul ~ PatWidth mul ~ E}b
+
+/patternfill{5 -1 $ @ ` Ji PatternCTM setmatrix PatternMatrix concat 0 2 ^ 2 ^
+
+M 0 1 mpstr length 1 sub{1 ^ mpstr 3 1 $ put}for ! 2 ^{currentpoint 5 ^{mpstr
+
+S}repeat YStep add M}repeat ! ! ! ! E}b}e
+
+
+
+L2? g{/mp/makepattern , |/hrf{6 eq setAorABC setpattern rectfill}b/hf{
+
+setAorABC setpattern O}b/hfW{setAorABC setpattern L}b/hs{setAorABC setpattern
+
+K}b/pf{pfprep setpattern O restore N}b/pfW{pfprep setpattern L restore N}b/ps{
+
+pfprep setpattern K restore N}b}e
+
+
+
+/iw 0 |/ih 0 |/im_save 0 |/s 0 |/polarity 0 |/smoothflag 0 |/mystring 0 |/bpc
+
+0 |/setup1asciiproc{[currentfile mystring/readhexstring cvx/! cvx]cvx bind}b
+
+/setup1binaryproc{[currentfile mystring/readstring cvx/! cvx]cvx bind}b
+
+/setup2asciiproc{currentfile/ASCII85Decode filter/RunLengthDecode filter}b
+
+/setup2binaryproc{currentfile/RunLengthDecode filter}b/mycolorspace{colspABC}|
+
+/myimagedict{/myimagedict 10 dict | myimagedict @ `/ImageType 1 |
+
+/MultipleDataSource F | E}b/imageprocarray[/setup1binaryproc/setup1asciiproc
+
+/setup2binaryproc/setup2asciiproc/setup1binarydecodeproc/setup1asciidecodeproc
+
+]|/L2Polarity{{[1 0]}{[0 1]}?}b/Q{/im_save save | imageprocarray ~ get/s ~ , |
+
+L2Polarity/polarity ~ |/smoothflag ~ | snap +/dx 2 ^ |/dy 1 ^ | +S/mystring ~
+
+string |/bpc ~ |/ih ~ |/iw ~ |}b/X{/im_save save | imageprocarray ~ get/s ~ ,
+
+| L2Polarity/polarity ~ |/smoothflag ~ | snap +/dx 2 ^ |/dy 1 ^ | +S/mystring
+
+~ string |/bpc ~ |/ih ~ |/iw ~ |}b/Z{im_save restore}b/Y{sgco myimagedict @ `
+
+/Width iw |/Height ih |/Decode polarity |/ImageMatrix[iw 0 0 ih 0 0]|
+
+/DataSource s |/BitsPerComponent 1 |/Interpolate smoothflag | E imagemask}b
+
+
+
+L2? not g{/setup2asciiproc{[/Level2ImagesError , aload ! T FatalErrorIf}b
+
+/setup2binaryproc/setup2asciiproc , |/L2Polarity{}|/Y{sgco iw ih polarity[iw 0
+
+0 ih 0 0]s imagemask}b}e
+
+
+
+L2? not g{/testsystemdict{where{systemdict eq{T}{F}?}{F}?}b/c 1 |/colorimage
+
+where{! T}{F}?{/c 0 statusdict `/processcolors where{! ! processcolors}{
+
+/deviceinfo where{! deviceinfo/Colors known{!{deviceinfo/Colors get}}if}if}? E
+
+| c 0 ne{/colorimage testsystemdict/setcolortransfer testsystemdict
+
+/currentcolortransfer testsystemdict/currentcmykcolor testsystemdict and and
+
+and not{/c 0 |}if}if}if c @ 1 ne ~ @ 3 ne ~ 4 ne and and{/c 0 |}if c 1 eq g{
+
+/expandbw{expandfactor mul round cvi bwclut ~ get 255 V}b/doclutimage{!/bwclut
+
+~ | bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/expandfactor ~ |[/expandbw ,/exec , @
+
+currenttransfer ~]cvx bind settransfer iw ih bpc[iw 0 0 ih 0 0]s image}b}e c @
+
+3 eq ~ 4 eq or g{/nullproc{{}}|/concatutil{/exec , 7 -1 $/exec ,}b/defsubclut{
+
+1 add getinterval |}b/spconcattransfer{/Dclut ~ |/Cclut ~ |/Bclut ~ |/Aclut ~
+
+|/ncompute ~ , | currentcolortransfer[{Aclut ncompute}concatutil]cvx[{Bclut
+
+ncompute}concatutil]cvx[{Cclut ncompute}concatutil]cvx[{Dclut ncompute}
+
+concatutil]cvx setcolortransfer}b/setuprgbcluts{/bit3x rgbclut length 3 sub |
+
+/bit1x bit3x 3 idiv |/rclut rgbclut |/gclut rclut 1 bit3x defsubclut/bclut
+
+rclut 2 bit3x defsubclut}b}e c 3 eq g{/3compute{~ bit3x mul round cvi get 255
+
+V}b/doclutimage{/rgbclut ~ | ! setuprgbcluts/3compute rclut gclut bclut @
+
+spconcattransfer iw ih bpc[iw 0 0 ih 0 0][s/exec ,/@ , @]cvx nullproc nullproc
+
+T 3 colorimage}b}e c 4 eq g{/ftoint{1 ~ sub 255 mul round cvi}b/stuffclut{
+
+cmykindex 3 -1 $ put}b/4compute{~ bit4x mul round cvi get 255 V}b
+
+/invalidcolortable? T |/computecmykclut{setuprgbcluts/bit4x rgbclut length 3
+
+idiv 4 mul 4 sub |/cmykclut bit4x 4 add string |/cclut cmykclut |/mclut cclut
+
+1 bit4x defsubclut/yclut cclut 2 bit4x defsubclut/kclut cclut 3 bit4x
+
+defsubclut/cmykindex 0 | 0 1 bit1x{@/cmykindex ~ bit1x ~ sub 4 mul | 3 mul @
+
+rclut ~ get 255 V ~ @ gclut ~ get 255 V ~ bclut ~ get 255 V setrgbcolor
+
+currentcmykcolor ftoint kclut stuffclut ftoint yclut stuffclut ftoint mclut
+
+stuffclut ftoint cclut stuffclut}for}b/doclutimage{/rgbclut ~ | !
+
+invalidcolortable?{computecmykclut}if/4compute cclut mclut yclut kclut
+
+spconcattransfer iw ih bpc[iw 0 0 ih 0 0][s/exec ,/@ , @ @]cvx nullproc
+
+nullproc nullproc T 4 colorimage}b}e c 0 eq g{/a{3 mul 3 getinterval
+
+putinterval ~ 3 add ~ 3 copy}b/8lookup/a , |/4lookup{/byte 1 ^ | -4 bitshift a
+
+byte 15 and a}b/2lookup{/byte 1 ^ | -6 bitshift a byte -4 bitshift 3 and a
+
+byte -2 bitshift 3 and a byte 3 and a}b/colorexpand{mystringexp 0 rgbclut 3
+
+copy 7 -1 $/mylookup , forall ! ! ! ! !}b/createexpandstr{/mystringexp ~
+
+mystring length mul string |}b/doclutimage{/rgbclut ~ | !/mylookup bpc 8 eq{3
+
+createexpandstr/8lookup}{bpc 4 eq{6 createexpandstr/4lookup}{12
+
+createexpandstr/2lookup}?}? , | iw ih bpc[iw 0 0 ih 0 0][s/exec ,/colorexpand
+
+,/exec ,]cvx F 3 colorimage}b}e/colorimage where{! T}{F}? g{/do24image{iw ih 8
+
+[iw 0 0 ih 0 0]s F 3 colorimage}b}DefIf_El{/rgbtogray{/str ~ |/len str length
+
+|/smlen len 3 idiv |/rstr str |/gstr str 1 len 1 sub getinterval |/bstr str 2
+
+len 2 sub getinterval | str @ 0 1 smlen 1 sub{@ 3 mul rstr 1 ^ get 0.3 mul
+
+gstr 2 ^ get 0.59 mul add bstr 3 -1 $ get 0.11 mul add round cvi put @}for ! 0
+
+smlen getinterval}b/do24image{iw ih 8[iw 0 0 ih 0 0][s/exec ,/rgbtogray ,/exec
+
+,]cvx bind image}b}e/doNimage{bpc 24 eq{do24image}{iw ih bpc[iw 0 0 ih 0 0]s
+
+image}?}b}e
+
+
+
+L2? g{/doclutimage{/rgbclut ~ | ! bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/hival ~ |[
+
+/Indexed colspABC hival rgbclut]setcolorspace myimagedict @ `/Width iw |
+
+/Height ih |/Decode[0 hival]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |
+
+/BitsPerComponent bpc |/Interpolate smoothflag | E image}b/doCMYKclutimage{
+
+/CMYKclut ~ | ! bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/hival ~ |[/Indexed/DeviceCMYK
+
+hival CMYKclut]setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode[0
+
+hival]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent bpc |
+
+/Interpolate smoothflag | E image}b/doNimage{bpc 24 eq{colspABC}{colspA}?
+
+setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode bpc 24 eq{[0 1 0 1
+
+0 1]}{[0 1]}? |/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent
+
+bpc 24 eq{8}{bpc}? |/Interpolate smoothflag | E image}b/doCMYKimage{
+
+/DeviceCMYK setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode[0 1 0
+
+1 0 1 0 1]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent 8 |
+
+/Interpolate smoothflag | E image}b}e
+
+
+
+/GreNewFont{10 dict @ 3 1 $ | @ ` 4 1 $/FontType 3 |/FontMatrix ~ |/FontBBox ~
+
+|/Encoding 256 array | 0 1 255{Encoding ~/.notdef put}for/CharProcs 257 dict |
+
+CharProcs/.notdef{}put/Metrics 257 dict | Metrics/.notdef 3 -1 $ put/BuildChar
+
+{/char ~ |/fontdict ~ |/charname fontdict/Encoding get char get | fontdict
+
+/Metrics get charname get aload ! setcachedevice fontdict ` Encoding char get
+
+CharProcs ~ get E exec}| E definefont !}|/AddChar{` Encoding 3 1 $ put
+
+CharProcs 3 1 $ put Metrics 3 1 $ put E}|
+
+
+
+/FEbuf 2 string |/FEglyph 3 string |/FE{(G00)FEglyph copy ! 1 ~{@ 16 lt{
+
+/offset 2 store}{/offset 1 store}? @ 16 FEbuf cvrs FEglyph ~ offset ~
+
+putinterval 1 ^ ~ FEglyph cvn put}for}bind |/Type1Hdr{11 dict `/FontName ~ |
+
+/PaintType ~ |/FontType 1 |/FontMatrix[1 3 ^ V 0 0 1 6 ^ V 0 0]| !/Encoding
+
+256 array 0 1 255{1 ^ ~/.notdef put}for 3 ^ 3 ^ FE | ! !/FontBBox{0 0 0 0}| &
+
+E currentfile eexec}bind |
+
+
+/pp 1 string |/ss 1 string |/rledecodebinary{/DC 0 |/BC 0 |{DC mystring length
+
+ge{exit}if currentfile ss readstring ! 0 get/BC ~ | BC 127 le{/BC BC 1 add |
+
+DC 1 DC BC add 1 sub{mystring ~ currentfile ss readstring ! 0 get put}for}{/BC
+
+257 BC sub | currentfile ss readstring ! 0 get/pp ~ | DC 1 DC BC add 1 sub{
+
+mystring ~ pp put}for}?/DC DC BC add |}loop mystring}b/rledecodeascii{/DC 0 |
+
+/BC 0 |{DC mystring length ge{exit}if currentfile ss readhexstring ! 0 get/BC
+
+~ | BC 127 le{/BC BC 1 add | DC 1 DC BC add 1 sub{mystring ~ currentfile ss
+
+readhexstring ! 0 get put}for}{/BC 257 BC sub | currentfile ss readhexstring !
+
+0 get/pp ~ | DC 1 DC BC add 1 sub{mystring ~ pp put}for}?/DC DC BC add |}loop
+
+mystring}b/setup1asciidecodeproc{[/rledecodeascii cvx]cvx bind}b
+
+/setup1binarydecodeproc{[/rledecodebinary cvx]cvx bind}b
+
+
+userdict/Pscript_Win_Compat 13 dict dup begin/bd{bind def}bind def/ld{load def
+
+}bd/CB{pop pop pop pop}bind def/B{pop pop pop pop}bind def/$x matrix def/SS{
+
+/pagesave save def}bind def/RS{/pagesave where{pop pagesave restore}{$x matrix
+
+invertmatrix concat}ifelse}bind def/ANSIVec[0/grave 1/acute 2/circumflex 3
+
+/tilde 4/macron 5/breve 6/dotaccent 7/dieresis 8/ring 9/cedilla 10
+
+/hungarumlaut 11/ogonek 12/caron 13/dotlessi 39/quotesingle 96/grave 124/bar
+
+130/quotesinglbase 131/florin 132/quotedblbase 133/ellipsis 134/dagger 135
+
+/daggerdbl 136/circumflex 137/perthousand 138/Scaron 139/guilsinglleft 140/OE
+
+145/quoteleft 146/quoteright 147/quotedblleft 148/quotedblright 149/bullet 150
+
+/endash 151/emdash 152/tilde 153/trademark 154/scaron 155/guilsinglright 156
+
+/oe 159/Ydieresis 160/space 161/exclamdown 164/currency 165/yen 166/brokenbar
+
+167/section 168/dieresis 169/copyright 170/ordfeminine 171/guillemotleft 172
+
+/logicalnot 173/hyphen 174/registered 175/macron 176/degree 177/plusminus 178
+
+/twosuperior 179/threesuperior 180/acute 181/mu 182/paragraph 183
+
+/periodcentered 184/cedilla 185/onesuperior 186/ordmasculine 187
+
+/guillemotright 188/onequarter 189/onehalf 190/threequarters 191/questiondown
+
+192/Agrave 193/Aacute 194/Acircumflex 195/Atilde 196/Adieresis 197/Aring 198
+
+/AE 199/Ccedilla 200/Egrave 201/Eacute 202/Ecircumflex 203/Edieresis 204
+
+/Igrave 205/Iacute 206/Icircumflex 207/Idieresis 208/Eth 209/Ntilde 210/Ograve
+
+211/Oacute 212/Ocircumflex 213/Otilde 214/Odieresis 215/multiply 216/Oslash
+
+217/Ugrave 218/Uacute 219/Ucircumflex 220/Udieresis 221/Yacute 222/Thorn 223
+
+/germandbls 224/agrave 225/aacute 226/acircumflex 227/atilde 228/adieresis 229
+
+/aring 230/ae 231/ccedilla 232/egrave 233/eacute 234/ecircumflex 235/edieresis
+
+236/igrave 237/iacute 238/icircumflex 239/idieresis 240/eth 241/ntilde 242
+
+/ograve 243/oacute 244/ocircumflex 245/otilde 246/odieresis 247/divide 248
+
+/oslash 249/ugrave 250/uacute 251/ucircumflex 252/udieresis 253/yacute 254
+
+/thorn 255/ydieresis]def currentdict{dup type/operatortype eq{[exch]cvx def}{
+
+pop pop}ifelse}forall/initialize{currentdict exch begin begin}bind def
+
+/terminate{/@FL where not{pop end end}{pop}ifelse}bind def/suspend/terminate
+
+load def/resume/initialize load def/M/moveto load def end put/Courier findfont
+
+10 scalefont setfont
+
+
+end /ProcSet defineresource pop
+
+
+
+
+
+
+Pscript_Win_Compat dup /initialize get exec
+
+[ 0 1.000 -1.000 0 0 0 ] false /Pscript_Win_Driver /ProcSet findresource dup /initialize get exec
+
+
+
+
+
+/mysetup [ 0.240 0 0 -0.240 8.880 592.800 ] | 
+
+
+
+
+
+
+userdict begin /pagesave save def end mysetup concat colspRefresh : 1.000 1.000 1.000 sco 0 0 2550 3300 rf ; 
+
+
+
+
+
+
+114 70 N M 1 1 rr 
+
+114 70 N M 3000 2250 rr : 1.000 1.000 1.000 sco O ; 
+
+114 70 N M 1 1 rr 
+
+114 70 N M 1 1 rr : 114 70 3000 2250 rc 
+
+114 70 N M 2726 1801 rr : 0.800 1.000 0.800 sco O ; 3 Lw 0 Lc 0 Lj solid 0.800 1.000 0.800 sco K ; 
+
+1901 491 N M -7 1 - -7 0 - -18 0 - -19 1 - -21 1 - -20 2 - -18 4 - -9 3 - -7 4 - -6 5 - -5 5 - -4 6 - -3 8 - -2 9 - -2 9 - -2 22 - 0 23 - 2 23 - 2 23 - 4 20 - 3 9 - 2 8 - 6 14 - 8 14 - 10 11 - 10 11 - 12 10 - 12 8 - 12 7 - 12 5 - 13 5 - 14 3 - 15 2 - 15 1 - 14 -1 - 15 -2 - 13 -3 - 11 -5 - 9 -7 - 8 -9 - 7 -11 - 6 -13 - 6 -12 - 6 -11 - 6 -10 - 6 -7 - 7 -4 - 5 -1 - 5 -1 - 6 1 - 6 2 - 7 1 - 8 1 - 11 1 - 13 0 - 16 -1 - 18 -1 - 18 -1 - 19 -1 - 19 0 - 18 1 - 16 3 - 8 2 - 7 3 - 16 9 - 14 11 - 15 10 - 13 10 - 13 7 - 6 3 - 6 1 - 6 0 - 5 -2 - 5 -3 - 5 -5 - 5 -6 - 5 -8 - 9 -17 - 9 -20 - 7 -20 - 5 -21 - 4 -18 - 1 -9 - 0 -7 - -1 -12 - -3 -11 - -5 -11 - -6 -9 - -9 -9 - -9 -9 - -10 -9 - -12 -10 - -13 -11 - -14 -11 - -16 -12 - -17 -12 - -18 -12 - -19 -9 - -20 -8 - -20 -5 - -11 -1 - -11 -1 - -26 1 - -27 3 - -27 5 - -27 5 - -25 6 - -11 2 - -10 3 - -8 2 - -8 2 - -6 2 - -5 2 - -4 1 - -3 2 - -3 4 - -1 4 - 0 4 - 0 3 - -2 3 - -3 2 - -5 1 - -5 0 - -11 -1 - -6 -1 - -8 -1 - -9 1 - -11 1 - C : 0.502 0.502 0.502 sco O ; 
+
+1893 482 N M -7 1 - -7 0 - -18 1 - -19 1 - -21 1 - -20 2 - -18 4 - -9 3 - -7 4 - -6 5 - -5 5 - -4 6 - -3 8 - -3 9 - -2 9 - -2 22 - 0 23 - 2 23 - 3 23 - 4 20 - 2 9 - 3 8 - 6 14 - 8 14 - 10 11 - 10 11 - 12 10 - 12 8 - 12 7 - 12 5 - 13 4 - 14 3 - 14 2 - 15 1 - 15 -1 - 14 -2 - 13 -3 - 11 -4 - 10 -7 - 8 -9 - 7 -12 - 6 -12 - 6 -12 - 6 -12 - 6 -9 - 6 -7 - 6 -4 - 6 -1 - 5 -1 - 5 1 - 6 2 - 7 1 - 9 1 - 11 1 - 13 0 - 16 -1 - 17 -1 - 19 -1 - 18 -1 - 19 0 - 18 1 - 16 3 - 8 2 - 7 3 - 16 9 - 14 10 - 15 11 - 14 10 - 13 7 - 6 2 - 6 1 - 6 0 - 5 -2 - 5 -3 - 5 -5 - 5 -6 - 5 -7 - 9 -18 - 8 -19 - 7 -21 - 5 -20 - 4 -19 - 1 -8 - 0 -7 - -1 -13 - -3 -11 - -5 -10 - -6 -9 - -8 -9 - -9 -9 - -11 -9 - -11 -10 - -13 -11 - -14 -12 - -16 -12 - -17 -12 - -18 -11 - -19 -9 - -20 -8 - -20 -5 - -11 -1 - -11 -1 - -26 1 - -27 3 - -28 5 - -26 5 - -25 6 - -11 2 - -10 3 - -8 2 - -8 2 - -6 2 - -5 1 - -4 2 - -3 2 - -3 4 - -2 4 - 0 3 - 0 3 - -1 3 - -4 2 - -5 1 - -4 1 - -11 -2 - -6 0 - -8 -1 - -9 0 - -11 1 - C : 0.200 0.200 0.800 sco O ; 
+
+2010 855 N M 62 -99 - 12 Lw 0 Lc 1 Lj solid 0 0.800 0.600 sco K 
+
+2095 773 N M 5 -63 - -53 33 - 48 30 - C : 0 0.800 0.600 sco O ; 
+
+1805 921 N M -11 1 - -14 1 - -15 0 - -16 1 - -16 2 - -14 4 - -12 5 - -4 4 - -4 4 - -3 5 - -3 6 - -3 15 - -2 17 - 0 18 - 1 19 - 3 18 - 3 16 - 4 14 - 5 12 - 6 10 - 7 9 - 8 9 - 18 14 - 19 10 - 10 4 - 11 2 - 11 2 - 12 0 - 12 0 - 10 -2 - 10 -2 - 9 -4 - 7 -5 - 6 -8 - 6 -9 - 5 -10 - 4 -10 - 5 -9 - 4 -8 - 5 -5 - 5 -3 - 4 -2 - 4 0 - 4 1 - 5 1 - 6 1 - 7 2 - 8 0 - 10 0 - 12 -1 - 14 -1 - 14 -1 - 29 0 - 14 1 - 13 2 - 12 4 - 11 7 - 12 8 - 11 9 - 10 7 - 10 6 - 5 2 - 5 1 - 4 -1 - 4 -1 - 4 -2 - 4 -4 - 4 -5 - 4 -6 - 7 -14 - 6 -15 - 6 -17 - 4 -16 - 3 -15 - 1 -12 - -1 -10 - -2 -9 - -4 -8 - -5 -8 - -6 -7 - -8 -7 - -17 -15 - -10 -9 - -11 -9 - -12 -10 - -13 -10 - -14 -8 - -15 -8 - -15 -6 - -16 -4 - -17 -1 - -20 0 - -21 3 - -21 3 - -21 4 - -19 5 - -16 4 - -7 2 - -6 1 - -5 1 - -3 2 - -6 3 - -2 3 - -1 3 - 0 5 - -1 3 - -3 1 - -4 1 - -4 0 - -8 -1 - -5 0 - -6 -1 - -7 0 - -8 1 - C : 0.502 0.502 0.502 sco O ; 
+
+1796 913 N M -11 1 - -13 0 - -15 1 - -16 1 - -16 1 - -14 4 - -12 5 - -5 4 - -4 4 - -3 5 - -2 6 - -4 15 - -1 17 - 0 18 - 1 19 - 2 18 - 3 16 - 4 14 - 5 12 - 6 10 - 8 10 - 8 8 - 9 8 - 9 7 - 10 5 - 9 5 - 10 3 - 11 3 - 23 2 - 22 -2 - 10 -3 - 9 -3 - 7 -5 - 6 -8 - 6 -9 - 5 -10 - 4 -10 - 5 -10 - 4 -7 - 5 -6 - 5 -3 - 4 -1 - 4 0 - 4 0 - 5 1 - 5 2 - 7 1 - 8 0 - 10 0 - 13 -1 - 13 -1 - 14 -1 - 29 0 - 14 1 - 13 2 - 12 5 - 12 7 - 11 8 - 12 9 - 10 7 - 10 6 - 5 2 - 5 1 - 4 -1 - 4 -1 - 4 -3 - 4 -4 - 4 -4 - 3 -6 - 8 -14 - 6 -16 - 5 -16 - 4 -17 - 3 -14 - 1 -13 - -1 -10 - -2 -9 - -4 -8 - -5 -7 - -6 -7 - -7 -8 - -17 -15 - -10 -8 - -11 -10 - -12 -10 - -14 -9 - -14 -9 - -14 -8 - -15 -6 - -16 -4 - -17 -1 - -20 1 - -21 2 - -21 4 - -21 4 - -19 5 - -16 4 - -7 2 - -6 1 - -5 1 - -3 2 - -6 3 - -2 3 - -1 3 - 0 5 - -1 2 - -3 2 - -4 1 - -4 0 - -8 -1 - -5 -1 - -6 0 - -7 0 - -9 1 - C : 0.200 0.200 0.800 sco O ; 
+
+1826 1255 N M 67 -96 - 0 0.800 0.600 sco K 
+
+1915 1178 N M 8 -63 - -55 30 - 47 33 - C : 0 0.800 0.600 sco O ; 
+
+1663 1307 N M -7 1 - -10 0 - -10 1 - -10 0 - -11 2 - -9 2 - -8 4 - -6 5 - -3 7 - -3 10 - -1 11 - 0 13 - 1 12 - 2 12 - 2 11 - 2 9 - 3 8 - 4 7 - 11 12 - 12 9 - 13 7 - 14 4 - 15 1 - 15 -1 - 6 -2 - 6 -2 - 5 -4 - 4 -5 - 4 -6 - 3 -6 - 3 -7 - 3 -6 - 3 -5 - 3 -4 - 3 -2 - 3 -1 - 6 0 - 6 2 - 5 1 - 5 0 - 7 0 - 8 -1 - 19 -1 - 19 0 - 10 1 - 8 1 - 8 3 - 8 5 - 15 11 - 7 5 - 6 4 - 6 2 - 6 -1 - 5 -5 - 5 -7 - 5 -9 - 5 -11 - 4 -11 - 2 -11 - 2 -10 - 1 -8 - -1 -7 - -1 -6 - -6 -10 - -9 -9 - -12 -10 - -14 -12 - -16 -13 - -10 -6 - -9 -5 - -11 -4 - -10 -3 - -11 -1 - -14 0 - -14 2 - -14 2 - -14 3 - -12 3 - -11 3 - -9 2 - -6 2 - -3 2 - -2 2 - 0 2 - 0 4 - -1 1 - -2 1 - -5 1 - -6 -1 - -7 0 - -4 0 - -6 0 - C : 0.502 0.502 0.502 sco O ; 
+
+1655 1299 N M -7 1 - -10 0 - -10 0 - -10 1 - -11 1 - -9 2 - -8 4 - -6 5 - -4 8 - -2 10 - -1 11 - 0 12 - 1 13 - 1 12 - 3 11 - 2 9 - 3 8 - 4 6 - 11 12 - 12 10 - 12 7 - 14 4 - 16 1 - 15 -1 - 6 -2 - 6 -2 - 5 -4 - 4 -5 - 7 -13 - 3 -6 - 3 -6 - 3 -5 - 3 -4 - 3 -2 - 3 -1 - 5 0 - 7 2 - 5 1 - 5 0 - 7 0 - 8 -1 - 19 -1 - 19 0 - 18 2 - 8 3 - 8 5 - 15 11 - 7 5 - 6 3 - 6 2 - 6 -1 - 5 -4 - 5 -7 - 5 -9 - 4 -11 - 7 -22 - 1 -10 - 1 -8 - -1 -7 - -1 -6 - -6 -10 - -9 -10 - -11 -10 - -14 -12 - -16 -13 - -10 -6 - -9 -5 - -11 -4 - -10 -2 - -12 -1 - -13 0 - -14 2 - -14 2 - -14 3 - -13 3 - -10 3 - -9 2 - -6 2 - -3 2 - -2 2 - 0 2 - 0 4 - -1 1 - -2 1 - -5 1 - -6 -1 - -7 -1 - -4 1 - -6 0 - C : 0.200 0.200 0.800 sco O ; 
+
+1611 1566 N M 85 -81 - 0 0.800 0.600 sco K 
+
+1714 1508 N M 21 -59 - -60 18 - 39 41 - C : 0 0.800 0.600 sco O ; 
+
+1410 1556 N M -4 1 - -6 0 - -13 1 - -12 2 - -5 2 - -4 3 - -2 5 - -1 6 - -1 15 - 1 15 - 2 7 - 1 6 - 5 9 - 6 7 - 8 6 - 8 4 - 8 3 - 10 1 - 9 -1 - 8 -3 - 3 -2 - 3 -3 - 4 -8 - 4 -8 - 2 -3 - 2 -2 - 3 -2 - 4 0 - 4 1 - 6 1 - 10 0 - 11 -1 - 12 0 - 11 1 - 5 2 - 5 3 - 10 7 - 4 3 - 5 2 - 3 1 - 4 -1 - 3 -3 - 3 -4 - 3 -5 - 3 -7 - 4 -14 - 1 -6 - 0 -5 - -1 -8 - -4 -7 - -5 -6 - -7 -6 - -9 -7 - -11 -8 - -11 -7 - -7 -2 - -6 -2 - -7 -1 - -9 1 - -17 2 - -9 2 - -8 2 - -7 1 - -5 1 - -4 1 - -2 2 - -1 1 - 0 1 - -1 3 - -1 1 - -3 1 - -3 -1 - -5 0 - -7 0 - C : 0.502 0.502 0.502 sco O ; 
+
+1402 1548 N M -4 1 - -6 0 - -13 1 - -7 0 - -6 2 - -4 2 - -4 3 - -2 5 - -2 6 - -1 7 - 0 7 - 2 16 - 1 6 - 2 6 - 4 9 - 7 8 - 7 6 - 8 4 - 9 2 - 10 1 - 9 -1 - 8 -2 - 3 -2 - 2 -4 - 4 -7 - 4 -8 - 2 -4 - 2 -2 - 4 -2 - 4 1 - 4 0 - 6 1 - 4 0 - 5 0 - 12 -1 - 12 0 - 11 1 - 5 2 - 5 3 - 9 7 - 5 3 - 4 2 - 4 2 - 3 -1 - 3 -3 - 4 -4 - 3 -6 - 2 -6 - 4 -14 - 2 -6 - 0 -5 - -1 -8 - -4 -7 - -6 -6 - -7 -6 - -9 -8 - -10 -8 - -12 -7 - -6 -2 - -7 -2 - -7 -1 - -8 1 - -18 2 - -9 2 - -8 2 - -7 2 - -5 1 - -3 1 - -2 2 - -1 1 - -1 1 - 0 3 - -1 1 - -3 1 - -4 -1 - -5 0 - -6 0 - C : 0.200 0.200 0.800 sco O ; 
+
+1190 1427 N M 83 83 - 0 0.800 0.600 sco K 
+
+1250 1528 N M 60 20 - -19 -60 - -41 40 - C : 0 0.800 0.600 sco O ; 
+
+693 492 N M -7 1 - -7 0 - -18 1 - -19 1 - -21 1 - -20 2 - -18 4 - -8 3 - -7 4 - -6 5 - -5 5 - -4 7 - -3 8 - -3 9 - -2 9 - -2 22 - 0 24 - 2 24 - 3 23 - 4 21 - 2 9 - 3 8 - 6 15 - 8 13 - 9 13 - 11 11 - 11 9 - 13 9 - 12 6 - 12 6 - 13 5 - 13 3 - 15 2 - 15 1 - 15 -1 - 14 -2 - 13 -3 - 11 -5 - 9 -7 - 8 -9 - 7 -12 - 7 -13 - 5 -12 - 6 -12 - 6 -10 - 7 -7 - 6 -4 - 6 -1 - 5 -1 - 5 1 - 6 2 - 7 1 - 8 1 - 11 1 - 13 0 - 16 -1 - 18 -1 - 18 -1 - 19 -1 - 19 0 - 18 1 - 16 3 - 8 2 - 7 4 - 16 8 - 14 11 - 15 11 - 13 10 - 7 4 - 6 4 - 6 2 - 6 1 - 6 0 - 5 -2 - 5 -3 - 5 -5 - 5 -7 - 5 -7 - 9 -18 - 9 -20 - 7 -21 - 5 -21 - 4 -19 - 1 -8 - 0 -8 - -1 -13 - -3 -11 - -5 -10 - -6 -10 - -9 -9 - -9 -9 - -10 -10 - -12 -10 - -13 -11 - -14 -12 - -16 -12 - -17 -12 - -18 -12 - -19 -10 - -20 -8 - -20 -5 - -11 -1 - -11 -1 - -25 1 - -27 4 - -28 4 - -27 6 - -24 6 - -11 2 - -10 3 - -9 2 - -8 2 - -6 2 - -5 2 - -4 2 - -2 1 - -4 4 - -1 4 - 0 4 - 0 3 - -1 3 - -4 2 - -5 1 - -5 1 - -11 -2 - -6 0 - -8 -1 - -9 0 - -11 1 - C : 0.502 0.502 0.502 sco O ; 
+
+685 484 N M -7 1 - -7 0 - -18 0 - -19 1 - -21 1 - -20 2 - -18 5 - -9 3 - -7 4 - -6 4 - -5 6 - -4 7 - -3 8 - -3 9 - -1 9 - -3 22 - 1 24 - 1 24 - 3 23 - 4 21 - 3 9 - 2 8 - 6 15 - 8 13 - 10 12 - 10 11 - 12 10 - 12 8 - 12 7 - 12 6 - 13 5 - 14 3 - 15 2 - 15 1 - 14 -1 - 15 -2 - 13 -3 - 11 -5 - 9 -7 - 8 -10 - 7 -11 - 6 -13 - 6 -13 - 6 -11 - 6 -10 - 6 -7 - 6 -4 - 6 -2 - 5 0 - 5 1 - 6 1 - 7 2 - 9 1 - 11 1 - 13 0 - 16 -1 - 17 -1 - 19 -1 - 18 -1 - 19 0 - 18 1 - 16 3 - 8 2 - 7 4 - 16 8 - 14 11 - 15 11 - 14 10 - 13 7 - 6 3 - 6 1 - 6 0 - 5 -2 - 5 -3 - 5 -5 - 5 -7 - 5 -7 - 9 -18 - 8 -20 - 7 -21 - 5 -21 - 4 -19 - 1 -9 - 0 -7 - -1 -13 - -3 -11 - -5 -11 - -6 -9 - -8 -10 - -9 -9 - -10 -9 - -12 -10 - -13 -11 - -14 -12 - -16 -12 - -17 -13 - -18 -11 - -19 -10 - -20 -8 - -20 -5 - -11 -1 - -11 -1 - -26 1 - -27 3 - -28 5 - -26 5 - -25 6 - -11 2 - -10 3 - -8 2 - -8 2 - -6 2 - -5 2 - -4 2 - -3 2 - -3 4 - -1 4 - 0 4 - 0 3 - -2 3 - -3 2 - -5 1 - -5 0 - -11 -1 - -6 -1 - -8 -1 - -9 1 - -11 1 - C : 0.200 0.200 0.800 sco O ; 
+
+873 919 N M -10 1 - -13 0 - -15 0 - -15 1 - -15 2 - -13 3 - -12 5 - -4 4 - -4 4 - -3 5 - -2 6 - -4 14 - -1 16 - 0 17 - 1 18 - 2 17 - 3 16 - 4 13 - 5 11 - 5 10 - 7 9 - 8 8 - 18 13 - 18 9 - 10 3 - 10 3 - 22 2 - 21 -2 - 10 -3 - 8 -3 - 7 -5 - 6 -7 - 5 -9 - 5 -9 - 4 -9 - 5 -9 - 4 -7 - 5 -5 - 4 -3 - 4 -2 - 4 0 - 4 1 - 4 1 - 5 1 - 7 2 - 8 0 - 10 0 - 12 -1 - 13 -1 - 13 -1 - 28 0 - 13 1 - 12 2 - 12 4 - 11 6 - 11 8 - 11 8 - 10 7 - 10 6 - 9 2 - 4 0 - 4 -1 - 4 -2 - 3 -4 - 8 -10 - 6 -13 - 7 -15 - 5 -16 - 4 -15 - 2 -14 - 1 -12 - -1 -10 - -2 -8 - -4 -8 - -4 -7 - -6 -7 - -7 -7 - -16 -14 - -10 -8 - -10 -9 - -12 -9 - -13 -9 - -13 -9 - -14 -7 - -15 -6 - -15 -4 - -16 -1 - -19 1 - -20 2 - -21 4 - -20 4 - -18 4 - -16 4 - -6 2 - -6 1 - -5 1 - -3 1 - -5 3 - -3 3 - 0 3 - 0 5 - -1 2 - -3 2 - -7 1 - -8 -1 - -5 -1 - -6 0 - -7 0 - -8 1 - C : 0.502 0.502 0.502 sco O ; 
+
+865 910 N M -11 1 - -12 1 - -15 0 - -15 1 - -15 2 - -13 3 - -12 5 - -4 4 - -4 4 - -3 5 - -2 6 - -4 13 - -1 17 - 0 17 - 1 18 - 2 17 - 3 15 - 4 13 - 5 11 - 5 10 - 7 9 - 8 8 - 18 14 - 18 9 - 9 3 - 10 3 - 22 2 - 22 -2 - 9 -3 - 9 -3 - 7 -5 - 6 -7 - 5 -9 - 5 -9 - 4 -10 - 4 -9 - 4 -7 - 5 -5 - 5 -3 - 4 -1 - 4 0 - 4 0 - 4 1 - 5 2 - 7 1 - 8 0 - 10 0 - 11 -1 - 13 -1 - 14 -1 - 28 0 - 13 1 - 12 2 - 12 4 - 11 7 - 11 8 - 11 8 - 10 7 - 9 6 - 9 2 - 4 0 - 4 -1 - 4 -2 - 4 -4 - 4 -5 - 3 -5 - 7 -14 - 6 -15 - 6 -15 - 4 -16 - 2 -14 - 1 -12 - -1 -9 - -2 -9 - -4 -8 - -4 -7 - -6 -6 - -7 -7 - -17 -14 - -9 -8 - -11 -9 - -11 -10 - -13 -9 - -13 -8 - -15 -7 - -14 -6 - -15 -4 - -17 -1 - -19 0 - -20 2 - -20 4 - -20 4 - -18 4 - -16 4 - -6 2 - -6 1 - -5 1 - -3 2 - -5 3 - -3 3 - 0 3 - 0 5 - -1 2 - -3 1 - -4 1 - -3 0 - -8 -1 - -5 0 - -6 -1 - -7 0 - -8 1 - C : 0.200 0.200 0.800 sco O ; 
+
+828 722 N M 72 115 - 0 0.800 0.600 sco K 
+
+874 851 N M 54 32 - -6 -62 - -48 30 - C : 0 0.800 0.600 sco O ; 
+
+1099 1307 N M -7 1 - -9 0 - -10 0 - -10 1 - -11 1 - -9 2 - -8 4 - -6 5 - -4 8 - -2 9 - -1 12 - 0 12 - 1 12 - 1 12 - 3 11 - 2 9 - 3 8 - 4 6 - 11 12 - 12 9 - 12 7 - 14 4 - 15 1 - 15 -1 - 13 -4 - 5 -3 - 4 -5 - 7 -13 - 5 -12 - 4 -5 - 3 -4 - 3 -2 - 3 -1 - 5 0 - 7 2 - 4 1 - 6 0 - 7 0 - 8 -1 - 18 -1 - 19 0 - 10 1 - 8 1 - 8 3 - 8 4 - 8 5 - 8 6 - 7 5 - 6 4 - 6 2 - 6 -1 - 5 -4 - 5 -7 - 5 -9 - 4 -11 - 7 -22 - 1 -10 - 1 -8 - -1 -6 - -1 -6 - -6 -10 - -9 -10 - -11 -10 - -14 -12 - -17 -12 - -9 -6 - -10 -5 - -10 -4 - -11 -3 - -11 -1 - -14 0 - -14 2 - -14 2 - -13 3 - -13 3 - -11 3 - -8 2 - -6 2 - -3 2 - -2 2 - 0 2 - 0 4 - -1 1 - -2 1 - -5 1 - -6 -1 - -7 -1 - -5 1 - -6 0 - C : 0.502 0.502 0.502 sco O ; 
+
+1091 1299 N M -7 1 - -9 0 - -10 0 - -11 0 - -10 2 - -10 2 - -7 4 - -6 5 - -4 7 - -2 10 - -1 11 - 0 12 - 0 12 - 2 12 - 2 11 - 3 9 - 3 8 - 4 6 - 10 12 - 12 10 - 13 7 - 14 4 - 15 1 - 15 -1 - 6 -2 - 6 -2 - 5 -4 - 4 -5 - 7 -13 - 3 -6 - 3 -6 - 3 -5 - 3 -4 - 3 -2 - 3 -1 - 6 0 - 7 2 - 4 1 - 6 0 - 7 0 - 8 -1 - 18 0 - 19 -1 - 10 1 - 8 1 - 8 3 - 8 5 - 15 11 - 7 5 - 6 3 - 6 2 - 6 -1 - 6 -4 - 5 -7 - 5 -9 - 4 -10 - 4 -11 - 3 -11 - 1 -10 - 1 -8 - -1 -7 - -1 -6 - -6 -10 - -9 -9 - -12 -10 - -14 -12 - -16 -13 - -10 -6 - -9 -5 - -11 -4 - -10 -2 - -11 -1 - -14 0 - -14 2 - -14 2 - -14 3 - -12 3 - -11 3 - -9 2 - -5 2 - -4 1 - -1 2 - -1 2 - 0 4 - -1 2 - -2 1 - -5 0 - -6 0 - -7 -1 - -4 0 - -6 1 - C : 0.200 0.200 0.800 sco O ; 
+
+988 1085 N M 73 116 - 0 0.800 0.600 sco K 
+
+1034 1214 N M 55 32 - -7 -62 - -48 30 - C : 0 0.800 0.600 sco O ; : 114 70 3000 2250 rc 0 0.400 0 sco %%IncludeFont: Helvetica-Bold
+
+(F0) cvn
+
+0.964 
+
+ (Helvetica-Bold) cvn /Type1 
+
+T 
+
+(Helvetica-Bold) cvn
+
+mF 
+
+(F0_83) cvn
+
+F0
+
+83 
+
+xF 
+
+F0_83
+
+Ji 
+
+-302.300 545 825 sR 
+
+0.074 0 (C)A 
+
+0.287 0 (o)A 
+
+0.852 0 (a)A 
+
+-0.287 0 (r)A 
+
+-0.148 0 (s)A 
+
+0.852 0 (e)A 
+
+0.287 0 (n)A 
+
+-0.074 0 (i)A 
+
+-0.361 0 32 0.287 0 (ng )D 
+
+-0.361 0 (P)A 
+
+1.287 0 (h)A 
+
+-0.148 0 (as)A 
+
+0.852 0 (e)A 
+
+eR 
+
+; 
+
+948 1648 N M 1227 151 rr : 114 70 3000 2250 rc 0 0.400 0 sco (F0_100) cvn
+
+F0
+
+100 
+
+xF 
+
+F0_100
+
+Ji 
+
+979 1664 M 
+
+0.200 0 (I)A 
+
+-0.100 0 (n)A 
+
+-0.800 0 (i)A 
+
+-0.300 0 (t)A 
+
+0.200 0 (i)A 
+
+0.400 0 (a)A 
+
+1.000 0 32 -0.800 0 (l )D 
+
+0.300 0 (P)A 
+
+-0.600 0 (a)A 
+
+0.100 0 (r)A 
+
+0.700 0 (t)A 
+
+-0.800 0 (i)A 
+
+0.700 0 (t)A 
+
+-0.800 0 (i)A 
+
+-0.100 0 (on)A 
+
+0.200 0 (i)A 
+
+-0.700 0 32 -0.100 0 (ng )D 
+
+0.300 0 (P)A 
+
+-0.100 0 (h)A 
+
+0.400 0 (a)A 
+
+-0.600 0 (s)A 
+
+0.400 0 (e)A 
+
+; : 114 70 3000 2250 rc 0 0.400 0 sco F0_100
+
+Ji 
+
+-60.400 2049 1326 sR 
+
+-0.200 0 (R)A 
+
+0.400 0 (e)A 
+
+-0.300 0 (f)A 
+
+0.200 0 (i)A 
+
+-0.100 0 (n)A 
+
+0.400 0 (e)A 
+
+0.100 0 (m)A 
+
+-0.600 0 (e)A 
+
+-0.100 0 (n)A 
+
+-1.500 0 32 0.700 0 (t )D 
+
+0.300 0 (P)A 
+
+-0.100 0 (h)A 
+
+0.400 0 (a)A 
+
+-0.600 0 (s)A 
+
+0.400 0 (e)A 
+
+eR 
+
+; 
+
+N 1425 1541.500 M 3 1 rr : 1.000 0 0 sco O ; 
+
+N 1423 1542.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1422 1543.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1423 1544.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1424 1545.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1425 1546.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1426 1547.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1427 1548.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 1428 1549.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 1429 1550.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 1430 1551.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 1431 1552.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 1433 1553.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1434 1554.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1435 1555.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 1436 1556.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 1437 1557.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 1438 1558.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 1439 1559.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 1441 1560.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1442 1561.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1443 1562.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1444 1563.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1445 1564.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1446 1565.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1447 1566.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1448 1567.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1449 1568.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1449 1569.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1450 1570.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1450 1571.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1450 1572.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1450 1573.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1450 1574.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1450 1575.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1449 1576.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1449 1577.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1449 1578.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1449 1579.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1449 1580.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1448 1581.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1448 1582.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1448 1583.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1448 1584.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1448 1585.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1448 1586.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1449 1587.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1450 1588.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1449 1589.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1450 1590.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1451 1591.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1451 1592.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1452 1593.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1453 1594.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1453 1595.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1454 1596.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1455 1597.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1456 1598.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1457 1599.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1458 1600.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 1459 1601.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 1460 1602.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 1461 1603.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 1462 1604.500 M 10 1 rr : 1.000 0 0 sco O ; 
+
+N 1464 1605.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 1465 1606.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 1466 1607.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1467 1608.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1469 1609.500 M 3 1 rr : 1.000 0 0 sco O ; 
+
+N 1470 1610.500 M 2 1 rr : 1.000 0 0 sco O ; 
+
+N 1690 1287.500 M 2 1 rr : 0 0 0 sco O ; 
+
+N 1690 1288.500 M 3 1 rr : 0 0 0 sco O ; 
+
+N 1689 1289.500 M 5 1 rr : 0 0 0 sco O ; 
+
+N 1689 1290.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1688 1291.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1689 1292.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1690 1293.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1691 1294.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 1692 1295.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 1694 1296.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1695 1297.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 1696 1298.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 1698 1299.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1699 1300.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1700 1301.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 1702 1302.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1703 1303.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1704 1304.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1705 1305.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1707 1306.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1708 1307.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1709 1308.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1710 1309.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1711 1310.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1712 1311.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1713 1312.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1714 1313.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1715 1314.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1716 1315.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1717 1316.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1718 1317.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1720 1318.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1721 1319.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1722 1320.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1723 1321.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1724 1322.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1725 1323.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1725 1324.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1726 1325.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1727 1326.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1728 1327.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1729 1328.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1729 1329.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1730 1330.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1731 1331.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1731 1332.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1731 1333.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1732 1334.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1732 1335.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1732 1336.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1732 1337.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1732 1338.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1732 1339.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1732 1340.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1732 1341.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1732 1342.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1732 1343.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1731 1344.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1731 1345.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1731 1346.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1731 1347.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1731 1348.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1731 1349.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1730 1350.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1730 1351.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1730 1352.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1730 1353.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1729 1354.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1729 1355.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1729 1356.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1729 1357.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1729 1358.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1729 1359.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1729 1360.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1729 1361.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1730 1362.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1730 1363.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1731 1364.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1732 1365.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1732 1366.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1733 1367.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1733 1368.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1733 1369.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1734 1370.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1735 1371.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1736 1372.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1737 1373.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1738 1374.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1739 1375.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1740 1376.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1741 1377.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1742 1378.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1744 1379.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1745 1380.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1746 1381.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1747 1382.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1748 1383.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1749 1384.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1750 1385.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1751 1386.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1752 1387.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1753 1388.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1754 1389.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1755 1390.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1756 1391.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1757 1392.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1758 1393.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1760 1394.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1761 1395.500 M 4 1 rr : 0 0 0 sco O ; 
+
+N 1762 1396.500 M 2 1 rr : 0 0 0 sco O ; 
+
+N 1726 1278.500 M 5 1 rr : 1.000 0 0 sco O ; 
+
+N 1724 1279.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1725 1280.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1725 1281.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1726 1282.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1726 1283.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1727 1284.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1728 1285.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1729 1286.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1730 1287.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1730 1288.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1731 1289.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1732 1290.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1733 1291.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1733 1292.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1734 1293.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1735 1294.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1735 1295.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1736 1296.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1737 1297.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1737 1298.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1738 1299.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1738 1300.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1739 1301.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1739 1302.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1740 1303.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1740 1304.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1741 1305.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1741 1306.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1742 1307.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1742 1308.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1742 1309.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1743 1310.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1743 1311.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1743 1312.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1743 1313.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1743 1314.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1743 1315.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1743 1316.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1743 1317.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1743 1318.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1742 1319.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1742 1320.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1742 1321.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1742 1322.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1741 1323.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1741 1324.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1740 1325.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1740 1326.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1738 1327.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1738 1328.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1737 1329.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1736 1330.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1736 1331.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1735 1332.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1734 1333.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1734 1334.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1733 1335.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1733 1336.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1732 1337.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1732 1338.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1731 1339.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1730 1340.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1730 1341.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1729 1342.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1729 1343.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1728 1344.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1728 1345.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1727 1346.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1726 1347.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1726 1348.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1725 1349.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1724 1350.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1724 1351.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1723 1352.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1722 1353.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1722 1354.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1721 1355.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1721 1356.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1720 1357.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1720 1358.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1719 1359.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1719 1360.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1719 1361.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1719 1362.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1718 1363.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1718 1364.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1718 1365.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1718 1366.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1718 1367.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1718 1368.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1718 1369.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1718 1370.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1718 1371.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1718 1372.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1718 1373.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1719 1374.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1719 1375.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1719 1376.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1720 1377.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1720 1378.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1721 1379.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1721 1380.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1722 1381.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1722 1382.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1723 1383.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1723 1384.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1724 1385.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1724 1386.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1725 1387.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1726 1388.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1726 1389.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1727 1390.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1728 1391.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1729 1392.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1729 1393.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1730 1394.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1731 1395.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1731 1396.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1731 1397.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1732 1398.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1732 1399.500 M 3 1 rr : 1.000 0 0 sco O ; 
+
+N 1905 881.500 M 4 1 rr : 0 0 0 sco O ; 
+
+N 1903 882.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1904 883.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1904 884.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1905 885.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1905 886.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1905 887.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1906 888.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1907 889.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1907 890.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1908 891.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1909 892.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1910 893.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1910 894.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1911 895.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1912 896.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1913 897.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1913 898.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1914 899.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1915 900.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1915 901.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1916 902.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1917 903.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1918 904.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1918 905.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1919 906.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1920 907.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1920 908.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1921 909.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1922 910.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1922 911.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1923 912.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1923 913.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1924 914.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1924 915.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1925 916.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1925 917.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1926 918.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1926 919.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1927 920.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1927 921.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1927 922.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1928 923.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1928 924.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1929 925.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1929 926.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1929 927.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1930 928.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1930 929.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1930 930.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1930 931.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1930 932.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1930 933.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1930 934.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1930 935.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1930 936.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1930 937.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1930 938.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1930 939.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1929 940.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1929 941.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1929 942.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1929 943.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1928 944.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1928 945.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1928 946.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1927 947.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1927 948.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1926 949.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1926 950.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1925 951.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1925 952.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1924 953.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1924 954.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1924 955.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1923 956.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1923 957.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1922 958.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1921 959.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1921 960.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1920 961.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1920 962.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1919 963.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1918 964.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1918 965.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1917 966.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1916 967.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1916 968.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1915 969.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1914 970.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1913 971.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1913 972.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1912 973.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1911 974.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1911 975.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1910 976.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1910 977.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1909 978.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1908 979.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1908 980.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1907 981.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1907 982.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1906 983.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1905 984.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1905 985.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1904 986.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1903 987.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1903 988.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1902 989.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1901 990.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1901 991.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1900 992.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1900 993.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1899 994.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1899 995.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1898 996.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1898 997.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1897 998.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1897 999.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1896 1000.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1896 1001.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1895 1002.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1895 1003.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1895 1004.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1894 1005.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1894 1006.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1894 1007.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1894 1008.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1893 1009.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1893 1010.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1893 1011.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1893 1012.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1893 1013.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1893 1014.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1893 1015.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1893 1016.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1893 1017.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1893 1018.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1893 1019.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1893 1020.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1894 1021.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1894 1022.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1894 1023.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1894 1024.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1895 1025.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1895 1026.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1895 1027.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1895 1028.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1896 1029.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1896 1030.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1897 1031.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1897 1032.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1898 1033.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1898 1034.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1899 1035.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1900 1036.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1900 1037.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1901 1038.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1901 1039.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1902 1040.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1902 1041.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1903 1042.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1904 1043.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1904 1044.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1905 1045.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1906 1046.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1906 1047.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1907 1048.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1908 1049.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1908 1050.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1909 1051.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1910 1052.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1910 1053.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1911 1054.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1912 1055.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 1912 1056.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1913 1057.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1913 1058.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1914 1059.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1915 1060.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1915 1061.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1916 1062.500 M 2 1 rr : 0 0 0 sco O ; 
+
+N 1871 885.500 M 2 1 rr : 1.000 0 0 sco O ; 
+
+N 1870 886.500 M 4 1 rr : 1.000 0 0 sco O ; 
+
+N 1869 887.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1868 888.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1869 889.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1870 890.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1871 891.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1872 892.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1873 893.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1874 894.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1875 895.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1876 896.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1877 897.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1878 898.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1879 899.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1880 900.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1881 901.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1882 902.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1883 903.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1884 904.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1885 905.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1886 906.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1886 907.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1887 908.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1888 909.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1889 910.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1890 911.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1891 912.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1892 913.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1892 914.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1893 915.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1894 916.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1895 917.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1896 918.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1896 919.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1897 920.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1898 921.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1898 922.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1899 923.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1899 924.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1900 925.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1900 926.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1901 927.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1901 928.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1902 929.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1902 930.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1903 931.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1903 932.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1904 933.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1904 934.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1905 935.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1905 936.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1906 937.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1906 938.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1907 939.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1907 940.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1908 941.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1908 942.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1909 943.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1909 944.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1910 945.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1910 946.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1911 947.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1911 948.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1912 949.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1912 950.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1913 951.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1913 952.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1914 953.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1914 954.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1915 955.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1915 956.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1916 957.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1916 958.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1917 959.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1917 960.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1918 961.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1918 962.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1919 963.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1919 964.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1919 965.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1920 966.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1920 967.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1921 968.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1921 969.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1922 970.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1922 971.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1923 972.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1924 973.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1924 974.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1925 975.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1925 976.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1926 977.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1926 978.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1927 979.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1928 980.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1929 981.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1929 982.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1930 983.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1931 984.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 1932 985.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 1933 986.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 1934 987.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 1935 988.500 M 10 1 rr : 1.000 0 0 sco O ; 
+
+N 1936 989.500 M 10 1 rr : 1.000 0 0 sco O ; 
+
+N 1938 990.500 M 10 1 rr : 1.000 0 0 sco O ; 
+
+N 1939 991.500 M 10 1 rr : 1.000 0 0 sco O ; 
+
+N 1940 992.500 M 10 1 rr : 1.000 0 0 sco O ; 
+
+N 1942 993.500 M 10 1 rr : 1.000 0 0 sco O ; 
+
+N 1943 994.500 M 10 1 rr : 1.000 0 0 sco O ; 
+
+N 1945 995.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 1946 996.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 1947 997.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 1949 998.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1950 999.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1951 1000.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1951 1001.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1952 1002.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1953 1003.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1953 1004.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1954 1005.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1954 1006.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1954 1007.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1954 1008.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1955 1009.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1955 1010.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1955 1011.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1955 1012.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1955 1013.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1955 1014.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1955 1015.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1016.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1017.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1018.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1019.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1020.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1021.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1022.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1023.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1024.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1025.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1026.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1027.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1028.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1029.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1030.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1031.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1032.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1033.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1034.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1035.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1036.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1037.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1038.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1956 1039.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1955 1040.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1955 1041.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1955 1042.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1955 1043.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1955 1044.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1955 1045.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1955 1046.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1955 1047.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1955 1048.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1955 1049.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1955 1050.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1955 1051.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1955 1052.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1955 1053.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1954 1054.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 1954 1055.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1954 1056.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1954 1057.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1954 1058.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1954 1059.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1954 1060.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1954 1061.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 1996 458.500 M 3 1 rr : 0 0 0 sco O ; 
+
+N 1994 459.500 M 5 1 rr : 0 0 0 sco O ; 
+
+N 1993 460.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1994 461.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 1994 462.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1995 463.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1996 464.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 1997 465.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1998 466.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 1999 467.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2000 468.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2001 469.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2003 470.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2004 471.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2005 472.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2006 473.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2007 474.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2009 475.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 2010 476.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 2011 477.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 2012 478.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 2013 479.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 2014 480.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2015 481.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2016 482.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2016 483.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 2017 484.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 2018 485.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 2019 486.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 2020 487.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 2021 488.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2022 489.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2023 490.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2023 491.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 2024 492.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 2025 493.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2026 494.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2027 495.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2027 496.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 2028 497.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2029 498.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2030 499.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2030 500.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 2031 501.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2032 502.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2033 503.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2033 504.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2034 505.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2034 506.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2035 507.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2035 508.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2036 509.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2037 510.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2037 511.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2038 512.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2038 513.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2039 514.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2039 515.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2040 516.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2040 517.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2041 518.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2041 519.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2042 520.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2042 521.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2043 522.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2043 523.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2044 524.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2044 525.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2045 526.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2045 527.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2046 528.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2046 529.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2047 530.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2047 531.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2048 532.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2048 533.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2049 534.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2049 535.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2050 536.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2050 537.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2051 538.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2051 539.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2052 540.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2052 541.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2053 542.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2053 543.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2054 544.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2054 545.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2055 546.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 547.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2055 548.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2056 549.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2056 550.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2057 551.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2057 552.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2058 553.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2058 554.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2059 555.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2059 556.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2059 557.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2060 558.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2060 559.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2061 560.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2062 561.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2062 562.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2063 563.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2063 564.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2064 565.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2065 566.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2065 567.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2066 568.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2067 569.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2067 570.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2068 571.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2068 572.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2069 573.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2070 574.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2070 575.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2071 576.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2072 577.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 2072 578.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2073 579.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2074 580.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 2075 581.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 2077 582.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 2078 583.500 M 11 1 rr : 0 0 0 sco O ; 
+
+N 2079 584.500 M 11 1 rr : 0 0 0 sco O ; 
+
+N 2081 585.500 M 11 1 rr : 0 0 0 sco O ; 
+
+N 2082 586.500 M 11 1 rr : 0 0 0 sco O ; 
+
+N 2084 587.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 2086 588.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 2087 589.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 2089 590.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2090 591.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 2091 592.500 M 10 1 rr : 0 0 0 sco O ; 
+
+N 2093 593.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2094 594.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2095 595.500 M 9 1 rr : 0 0 0 sco O ; 
+
+N 2097 596.500 M 8 1 rr : 0 0 0 sco O ; 
+
+N 2098 597.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2099 598.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2100 599.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2100 600.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2101 601.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2102 602.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2102 603.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2103 604.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2103 605.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2104 606.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2104 607.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2104 608.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2105 609.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2105 610.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2105 611.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2105 612.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2106 613.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 614.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 615.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 616.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 617.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 618.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2107 619.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2107 620.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2107 621.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2107 622.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2107 623.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2107 624.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2107 625.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2107 626.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2107 627.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2107 628.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2107 629.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2107 630.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2107 631.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2107 632.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2107 633.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 634.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2106 635.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 636.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 637.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 638.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 639.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 640.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 641.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 642.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 643.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 644.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 645.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 646.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 647.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 648.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 649.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 650.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 651.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 652.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 653.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 654.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 655.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 656.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 657.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2106 658.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2105 659.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2105 660.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2105 661.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2105 662.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2105 663.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2105 664.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2105 665.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2105 666.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2105 667.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2104 668.500 M 7 1 rr : 0 0 0 sco O ; 
+
+N 2104 669.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2104 670.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2104 671.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2104 672.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2104 673.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2104 674.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2104 675.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2104 676.500 M 6 1 rr : 0 0 0 sco O ; 
+
+N 2046 440.500 M 3 1 rr : 1.000 0 0 sco O ; 
+
+N 2044 441.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2043 442.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2044 443.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2045 444.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2045 445.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 2046 446.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 2047 447.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2048 448.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2049 449.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2049 450.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 2050 451.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 2051 452.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2052 453.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2053 454.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2053 455.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 2054 456.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2055 457.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2056 458.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2056 459.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 2057 460.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2058 461.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2059 462.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2059 463.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 2060 464.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2061 465.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2062 466.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2062 467.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2063 468.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2064 469.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2064 470.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 2065 471.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2066 472.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2067 473.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2067 474.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2068 475.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2069 476.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2069 477.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2070 478.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2071 479.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2071 480.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 2072 481.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2073 482.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2074 483.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2074 484.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2075 485.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2076 486.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2076 487.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2077 488.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2078 489.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2078 490.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2079 491.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2079 492.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2080 493.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2081 494.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2081 495.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2082 496.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2082 497.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2082 498.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2083 499.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2083 500.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2083 501.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2084 502.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2084 503.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2084 504.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2084 505.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2085 506.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2085 507.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2085 508.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2086 509.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2086 510.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2086 511.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2086 512.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 513.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 514.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 515.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 516.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 517.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 518.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 519.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 520.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 521.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 522.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 523.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 524.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 525.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 526.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 527.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 528.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 529.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 530.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 531.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 532.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 533.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 534.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 535.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2087 536.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2086 537.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2086 538.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2086 539.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2086 540.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2086 541.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2086 542.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2086 543.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2086 544.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2085 545.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2085 546.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2085 547.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2084 548.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2084 549.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2084 550.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2084 551.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2084 552.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2083 553.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2083 554.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2083 555.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2082 556.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2082 557.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2081 558.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2080 559.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 2080 560.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2079 561.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2077 562.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 2076 563.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 2074 564.500 M 10 1 rr : 1.000 0 0 sco O ; 
+
+N 2072 565.500 M 11 1 rr : 1.000 0 0 sco O ; 
+
+N 2071 566.500 M 11 1 rr : 1.000 0 0 sco O ; 
+
+N 2069 567.500 M 11 1 rr : 1.000 0 0 sco O ; 
+
+N 2068 568.500 M 11 1 rr : 1.000 0 0 sco O ; 
+
+N 2066 569.500 M 11 1 rr : 1.000 0 0 sco O ; 
+
+N 2064 570.500 M 11 1 rr : 1.000 0 0 sco O ; 
+
+N 2063 571.500 M 11 1 rr : 1.000 0 0 sco O ; 
+
+N 2061 572.500 M 11 1 rr : 1.000 0 0 sco O ; 
+
+N 2060 573.500 M 11 1 rr : 1.000 0 0 sco O ; 
+
+N 2059 574.500 M 10 1 rr : 1.000 0 0 sco O ; 
+
+N 2058 575.500 M 9 1 rr : 1.000 0 0 sco O ; 
+
+N 2058 576.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 2057 577.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2056 578.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2055 579.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 2054 580.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 2053 581.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 2052 582.500 M 8 1 rr : 1.000 0 0 sco O ; 
+
+N 2052 583.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2051 584.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2051 585.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2050 586.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2049 587.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2049 588.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2049 589.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2048 590.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2048 591.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2048 592.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2048 593.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2048 594.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2047 595.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2047 596.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2047 597.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2047 598.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2047 599.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2047 600.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2048 601.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2048 602.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2048 603.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2048 604.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2048 605.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2048 606.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2049 607.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2049 608.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2049 609.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2049 610.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2050 611.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2050 612.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2050 613.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2050 614.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2051 615.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2051 616.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2051 617.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2052 618.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2052 619.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2052 620.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2053 621.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2053 622.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2053 623.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2054 624.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2054 625.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2054 626.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2055 627.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2055 628.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2055 629.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2056 630.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2056 631.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2056 632.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2057 633.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2057 634.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2058 635.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2058 636.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2059 637.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2059 638.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2060 639.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2060 640.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2060 641.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2061 642.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2061 643.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2062 644.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2062 645.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2062 646.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2063 647.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2063 648.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2064 649.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2064 650.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2064 651.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2065 652.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2065 653.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2066 654.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2066 655.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2066 656.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2067 657.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2067 658.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2068 659.500 M 6 1 rr : 1.000 0 0 sco O ; 
+
+N 2068 660.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2068 661.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2069 662.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2069 663.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2070 664.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2070 665.500 M 7 1 rr : 1.000 0 0 sco O ; 
+
+N 2071 666.500 M 2 1 rr : 1.000 0 0 sco O ; 
+
+164 95 N M 2601 271 rr : 114 70 3000 2250 rc 0.647 0 0.129 sco F0_100
+
+Ji 
+
+201 111 M 
+
+-0.300 0 (M)A 
+
+-0.100 0 (u)A 
+
+0.200 0 (l)A 
+
+-0.300 0 (t)A 
+
+0.200 0 (i)A 
+
+-0.800 0 (l)A 
+
+0.400 0 (eve)A 
+
+1.000 0 32 -0.800 0 (l )D 
+
+-0.100 0 (p)A 
+
+-0.600 0 (a)A 
+
+0.100 0 (r)A 
+
+0.700 0 (t)A 
+
+-0.800 0 (i)A 
+
+0.700 0 (t)A 
+
+-0.800 0 (i)A 
+
+-0.100 0 (on)A 
+
+0.200 0 (i)A 
+
+-0.700 0 32 -0.100 0 (ng )D 
+
+0.400 0 (a)A 
+
+0.200 0 (l)A 
+
+-0.100 0 (g)A 
+
+-1.100 0 (o)A 
+
+1.100 0 (r)A 
+
+-0.800 0 (i)A 
+
+-0.300 0 (t)A 
+
+-0.100 0 (h)A 
+
+0.100 0 (m)A 
+
+-0.200 0 32 0.400 0 (s c)D 
+
+-1.100 0 (o)A 
+
+1.100 0 (m)A 
+
+-1.100 0 (p)A 
+
+-0.100 0 (u)A 
+
+0.700 0 (t)A 
+
+0.800 0 32 -0.600 0 (e )D 
+
+-1.200 0 32 0.400 0 (a )D 
+
+-0.100 0 (p)A 
+
+0.400 0 (a)A 
+
+0.100 0 (r)A 
+
+-0.300 0 (t)A 
+
+0.200 0 (i)A 
+
+-0.300 0 (t)A 
+
+0.200 0 (i)A 
+
+-0.100 0 (on)A 
+
+; : 114 70 3000 2250 rc 0.647 0 0.129 sco F0_100
+
+Ji 
+
+273 231 M 
+
+0.400 0 (a)A 
+
+0.500 0 32 -0.300 0 (t t)D 
+
+-0.100 0 (h)A 
+
+-1.200 0 32 0.400 0 (e c)D 
+
+-0.100 0 (o)A 
+
+0.400 0 (a)A 
+
+0.100 0 (r)A 
+
+-0.600 0 (s)A 
+
+0.400 0 (es)A 
+
+0.500 0 32 -0.300 0 (t )D 
+
+-0.100 0 (g)A 
+
+0.100 0 (r)A 
+
+0.400 0 (a)A 
+
+-1.100 0 (p)A 
+
+0.300 0 32 -0.100 0 (h )D 
+
+0.400 0 (a)A 
+
+-0.700 0 32 -0.100 0 (nd )D 
+
+0.700 0 (t)A 
+
+-1.100 0 (h)A 
+
+0.400 0 (e)A 
+
+0.300 0 32 -0.100 0 (n )D 
+
+0.100 0 (r)A 
+
+-0.600 0 (e)A 
+
+0.700 0 (f)A 
+
+-0.800 0 (i)A 
+
+-0.100 0 (n)A 
+
+-0.200 0 32 0.400 0 (e )D 
+
+-0.300 0 (t)A 
+
+-0.100 0 (h)A 
+
+-1.200 0 32 0.400 0 (e s)D 
+
+-0.100 0 (o)A 
+
+0.200 0 (l)A 
+
+-1.100 0 (u)A 
+
+0.700 0 (t)A 
+
+-0.800 0 (i)A 
+
+-0.100 0 (on)A 
+
+0.700 0 (!)A 
+
+; 
+
+LH 
+
+pagesave restore
+
+
+
+
+
+
+
+/Pscript_Win_Driver /ProcSet findresource dup /terminate get exec
+
+Pscript_Win_Compat dup /terminate get exec
+
+
+
+restore gr
+%
+% End Imported PIC File: slide8.eps
+%
+/Helvetica-Bold findfont 300.00 scalefont setfont
+14550 7514 m
+gs 1 -1 sc (\(b\)) col-1 show gr
+/Helvetica-Bold findfont 300.00 scalefont setfont
+5100 5864 m
+gs 1 -1 sc (\(a\)) col-1 show gr
+$F2psEnd
+restore
+%%EndDocument
+ @endspecial 678 2789 a Fy(Figure)e(1)p FL(:)26 b Fx(\(a\))18
+b(T)-8 b(r)o(aditional)18 b(par)s(titioning)g(algor)q(ithms)o(.)k
+(\(b\))c(Multile)n(v)n(el)h(par)s(titioning)f(algor)q(ithms)o(.)100
+2982 y FL(The)h(adv)n(antages)g(of)j Fz(M)l FG(E)-17
+b Fz(T)g FG(I)p Fz(S)24 b FL(compared)19 b(to)h(other)f(similar)i
+(packages)e(are)h(the)g(follo)n(wing:)88 3167 y Fw(+)42
+b FC(Pr)o(o)o(vides)19 b(high)i(quality)f(partitions!)208
+3277 y FL(Experiments)j(on)i(a)h(lar)o(ge)f(number)e(of)j(graphs)e
+(arising)h(in)g(v)n(arious)g(domains)f(including)g(\002nite)i(element)f
+(methods,)g(linear)208 3386 y(programming,)g(VLSI,)i(and)g
+(transportation)e(sho)n(w)h(that)k Fz(M)l FG(E)-17 b
+Fz(T)g FG(I)p Fz(S)31 b FL(produces)26 b(partitions)g(that)i(are)f
+(consistently)f(better)h(than)208 3496 y(those)g(produced)f(by)h(other)
+g(widely)g(used)h(algorithms.)47 b(The)27 b(partitions)g(produced)e(by)
+30 b Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)32 b FL(are)c(consistently)f
+(10\045)g(to)208 3606 y(50\045)19 b(better)h(than)g(those)g(produced)e
+(by)h(spectral)h(partitioning)f(algorithms)g([1)o(,)h(4].)88
+3790 y Fw(+)42 b FC(It)20 b(is)h(extr)o(emely)e(fast!)208
+3900 y FL(Experiments)d(on)i(a)g(wide)g(range)f(of)h(graphs)f(has)i
+(sho)n(wn)e(that)j Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)23
+b FL(is)c(one)e(to)i(tw)o(o)f(orders)f(of)h(magnitude)e(f)o(aster)j
+(than)e(other)208 4010 y(widely)h(used)h(partitioning)e(algorithms.)24
+b(Figure)18 b(2)i(sho)n(ws)f(the)g(amount)f(of)h(time)g(required)e(to)j
+(partition)e(a)i(v)n(ariety)e(of)h(graphs)208 4119 y(in)h(256)g(parts)h
+(for)f(tw)o(o)g(dif)n(ferent)f(architectures,)g(an)i(R10000-based)d
+(SGI)j(Challenge)f(and)g(a)h(Pentium)f(Pro-based)f(personal)208
+4229 y(computer)-5 b(.)30 b(Graphs)21 b(containing)g(up)h(to)g(four)f
+(million)h(v)o(ertices)g(can)g(be)g(partitioned)f(in)i(256)e(parts)h
+(in)h(well)g(under)e(a)h(minute)208 4338 y(on)g(today')-5
+b(s)22 b(scienti\002c)h(w)o(orkstations.)33 b(The)22
+b(run)g(time)h(of)i Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)27
+b FL(is)d(comparable)c(to)j(\(or)g(e)n(v)o(en)f(smaller)g(than\))g(the)
+h(run)f(time)208 4448 y(of)d(some)h(geometric)f(partitioning)f
+(algorithms)h(that)i(often)e(produce)f(much)h(w)o(orse)i(partitions.)88
+4633 y Fw(+)42 b FC(Pr)o(o)o(vides)19 b(lo)o(w)h(\002ll)i(orderings!)
+208 4742 y FL(The)29 b(\002ll-reducing)f(orderings)g(produced)f(by)32
+b Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)34 b FL(are)c(substantially)f
+(better)g(than)h(those)f(produced)f(by)h(other)g(widely)208
+4852 y(used)18 b(algorithms)g(including)g(multiple)g(minimum)g(de)o
+(gree.)23 b(F)o(or)18 b(man)o(y)g(classes)j(of)d(problems)g(arising)h
+(in)g(scienti\002c)g(compu-)208 4962 y(tations)k(and)g(linear)g
+(programming,)f Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)27
+b FL(is)e(able)e(to)g(reduce)g(the)g(storage)f(and)h(computational)e
+(requirements)g(of)j(sparse)208 5071 y(matrix)e(f)o(actorization)f
+(methods)g(by)h(up)h(to)g(an)f(order)g(of)g(magnitude.)31
+b(Moreo)o(v)o(er)m(,)20 b(unlik)o(e)i(multiple)g(minimum)f(de)o(gree,)h
+(the)208 5181 y(elimination)f(trees)h(produced)e(by)k
+Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)27 b FL(are)22 b(suited)g(for)g
+(parallel)g(direct)f(f)o(actorization.)30 b(Furthermore,)20
+b(as)j(Figure)f(2)g(illus-)208 5290 y(trates,)g Fz(M)l
+FG(E)-17 b Fz(T)g FG(I)p Fz(S)24 b FL(is)d(able)e(to)h(compute)f(these)
+h(ordering)e(v)o(ery)g(f)o(ast.)26 b(Matrices)20 b(with)g(o)o(v)o(er)e
+(tw)o(o)i(hundred)e(thousand)g(ro)n(ws)i(can)g(be)208
+5400 y(reordered)d(in)k(just)f(a)h(fe)n(w)f(seconds)g(on)g(current)e
+(generation)h(w)o(orkstations)g(and)g(PCs.)1929 5649
+y(4)p eop
+%%Page: 5 5
+5 4 bop 690 3717 a @beginspecial 0 @llx 0 @lly 716 @urx
+1056 @ury 3024 @rwi @setspecial
+%%BeginDocument: ./figures/slides.eps
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+-30.0 1113.0 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+  bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+  4 -2 roll mul srgb} bind def
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+10 setmiterlimit
+n -1000 19537 m -1000 -1000 l 13423 -1000 l 13423 19537 l cp clip
+ 0.06000 0.06000 sc
+% Polyline
+%
+% Begin Imported EPS File: slide1.eps
+%
+n gs
+525 973 tr
+16.646067 -16.638623 sc
+0 -523 tr
+-40 -50 tr
+sa
+n 40 50 m 752 50 l 752 573 l 40 573 l cp clip
+countdictstack
+mark
+/showpage {} def
+% EPS file follows:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/defineresource where{pop}{userdict begin/defineresource{userdict/Resources 2
+
+copy known{get begin}{15 dict dup begin put}ifelse exch readonly exch
+
+currentdict 1 index known not{dup 30 dict def}if load 3 -1 roll 2 index put
+
+end}bind readonly def/findresource{userdict/Resources get exch get exch get}
+
+bind readonly def/resourceforall{pop pop pop pop}bind readonly def
+
+/resourcestatus{userdict/Resources 2 copy known{get exch 2 copy known{get exch
+
+known{0 -1 true}{pop pop false}ifelse}{pop pop pop false}ifelse}{pop pop false
+
+}ifelse}bind readonly def end}ifelse
+
+
+
+/Pscript_Win_Driver 200 dict dup begin
+
+
+/FatalErrorIf{{initgraphics findfont exch scalefont setfont counttomark 3 div
+
+cvi{moveto show}repeat showpage quit}{cleartomark}ifelse}bind def
+
+
+/VM? {vmstatus exch sub exch pop gt { [
+
+(This job requires more memory than is available in this printer.) 100 500
+
+(Try one or more of the following, and then print again:) 100 485
+
+(In the PostScript dialog box, click Optimize For Portability.) 115 470
+
+(In the Device Options dialog box, make sure the Available Printer Memory is accurate.) 115 455
+
+(Reduce the number of fonts in the document.) 115 440
+
+(Print the document in parts.) 115 425
+
+12 /Times-Roman showpage
+
+(%%[ PrinterError: Low Printer VM ]%%) =
+
+true FatalErrorIf}if} bind def
+
+
+/|/def load def/,/load load |/~/exch , |/?/ifelse , |/!/pop , |/`/begin , |/^
+
+/index , |/@/dup , |/+/translate , |/$/roll , |/U/userdict , |/M/moveto , |/-
+
+/rlineto , |/&/currentdict , |/:/gsave , |/;/grestore , |/F/false , |/T/true ,
+
+|/N/newpath , |/E/end , |/Ac/arc , |/An/arcn , |/A/ashow , |/D/awidthshow , |
+
+/C/closepath , |/V/div , |/O/eofill , |/L/fill , |/I/lineto , |/-C/rcurveto ,
+
+|/-M/rmoveto , |/+S/scale , |/Ji/setfont , |/Lc/setlinecap , |/Lj/setlinejoin
+
+, |/Lw/setlinewidth , |/S/show , |/LH/showpage , |/K/stroke , |/W/widthshow ,
+
+|/R/rotate , |/b{bind |}bind |/bd{bind |}bind |/xd{~ |}bd/ld{, |}bd/lw/Lw ld
+
+/lc/Lc ld/lj/Lj ld/sg/setgray ld/L2? F/languagelevel where{! languagelevel 2
+
+ge{! T}if}if |/g{@ not{U/DefIf_save save put}if U/DefIf_bool 2 ^ put}b
+
+/DefIf_El{if U/DefIf_bool get not @{U/DefIf_save get restore}if}b/e{DefIf_El !
+
+}b/self & |/reinitialize{[/TextInit/GraphInit/UtilsInit counttomark{@ where{
+
+self eq}{F}?{cvx exec}{!}?}repeat cleartomark}b/initialize{`{/ADO_mxRot ~ |
+
+/TextInitialised? F | reinitialize E}{U/Pscript_Win_Data 200 dict @ ` put
+
+/ADO_mxRot ~ |/TextInitialised? F | reinitialize}?}b/terminate{!{& self eq{
+
+exit}{E}?}loop E}b/suspend/terminate , |/resume{` Pscript_Win_Data `}b/snap{
+
+transform 0.25 sub round 0.25 add ~ 0.25 sub round 0.25 add ~ itransform}b
+
+/dsnap{dtransform round ~ round ~ idtransform}b<04>cvn{}|/setjn{{statusdict
+
+/jobname known{statusdict/jobname 3 -1 $ put}if}stopped cleartomark}b/solid{[]
+
+0 setdash}b/setdsh{0 setdash}b/colspRefresh{}b/rp{4 2 $ M 1 ^ 0 - 0 ~ - neg 0
+
+-}b/rr{1 ^ 0 - 0 ~ - neg 0 - C}b
+
+
+
+L2? not g{/rf{N rp L}b/fx{1 1 dtransform @ 0 ge{1 sub 1}{1 add -0.25}? 3 -1 $
+
+@ 0 ge{1 sub 1}{1 add -0.25}? 3 1 $ 4 1 $ idtransform 4 -2 $ idtransform}b/BZ{
+
+4 -2 $ snap + +S fx rf}b/rs{N rp C K}b/rc{N rp clip N}b/sg{setgray}b/sco{
+
+setrgbcolor}b/sgco{{sg}{sco}?}b}e
+
+
+
+L2? g{/colspA/DeviceGray |/colspABC/DeviceRGB |/setAorABC{{colspA}{colspABC}?
+
+setcolorspace}b/rf/rectfill , |/fx{1 1 dtransform @ 0 ge{1 sub 0.5}{1 add -0.5
+
+}? 3 -1 $ @ 0 ge{1 sub 0.5}{1 add -0.5}? 3 1 $ 4 1 $ idtransform 4 -2 $
+
+idtransform}b/BZ{4 -2 $ snap + +S fx rf}b/rs/rectstroke , |/rc/rectclip , |/sg
+
+{@ @ setcolor}b/sco{setcolor}b/colspRefresh{colspABC setcolorspace}b/sgco{{sg
+
+}{sco}?}b/UtilsInit{F setglobal}b/definecolorrendering{/ColorRendering
+
+defineresource !}b/findcolorrendering{@/ColorRendering resourcestatus{! !
+
+/ColorRendering findresource T}{! F}?}b/selectcolorrendering{@/ColorRendering
+
+resourcestatus{! !/ColorRendering}{!/DefaultColorRendering/ColorRendering}?
+
+findresource setcolorrendering}b}e
+
+
+
+/bullets{{/bullet}repeat}b/ANSIEncoding[/grave/acute/circumflex/tilde/macron
+
+/breve/dotaccent/dieresis/ring/cedilla/hungarumlaut/ogonek/caron/dotlessi 18
+
+bullets StandardEncoding 32 95 getinterval aload ! 3 bullets/quotesinglbase
+
+/florin/quotedblbase/ellipsis/dagger/daggerdbl/circumflex/perthousand/Scaron
+
+/guilsinglleft/OE 4 bullets/quoteleft/quoteright/quotedblleft/quotedblright
+
+/bullet/endash/emdash/tilde/trademark/scaron/guilsinglright/oe 2 bullets
+
+/Ydieresis/space/exclamdown/cent/sterling/currency/yen/brokenbar/section
+
+/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered
+
+/macron/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph
+
+/periodcentered/cedilla/onesuperior/ordmasculine/guillemotright/onequarter
+
+/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis
+
+/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute
+
+/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
+
+/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
+
+/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute
+
+/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve
+
+/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex
+
+/udieresis/yacute/thorn/ydieresis]| ANSIEncoding @ 39/quotesingle put 96/grave
+
+put/ANSIEncodingOld ANSIEncoding 256 array copy | ANSIEncodingOld @[138 153
+
+154 169 172 174 177 178 179 181 185 188 189 190 208 215 221 222 240 247 253
+
+254]{/bullet put @}forall 166/bar put 176/ring put
+
+
+
+/TextInit{TextInitialised? not{/Pscript_Windows_Font & |/TextInitialised? T |
+
+/fM[1 0 0 -1 0 0]|/mFM matrix |/iMat[1 0 0.212557 neg 1 0 0]|}if}b/xUP null |
+
+/yUP null |/uW null |/xSP null |/ySP null |/sW null |/copyfont{1 ^ length add
+
+dict `{1 ^/FID ne{|}{! !}?}forall & E}b/rF{3 copyfont @ `/Encoding
+
+ANSIEncoding &/CharStrings known{CharStrings/Eth known not{! ANSIEncodingOld}
+
+if}if | E}b/mF{findfont ~{@/Encoding get @ StandardEncoding eq{! T}{{
+
+ISOLatin1Encoding}stopped{! F}{eq}?{T}{@ ` T 32 1 127{Encoding 1 ^ get
+
+StandardEncoding 3 -1 $ get eq and}for E}?}?}{F}?{rF}{3 copyfont}? `
+
+/OrigFontType ~ |/OrigFontName ~ | & E 2 ^ ~ definefont fM 5 4 -1 $ put fM 4 0
+
+put fM makefont Pscript_Windows_Font 3 1 $ put}b/xF{scalefont
+
+Pscript_Windows_Font 3 1 $ put}b/xMF{mFM astore makefont Pscript_Windows_Font
+
+3 1 $ put}b/xF2/scalefont , |/xMF2{mFM astore makefont}b/sLT{: Lw -M
+
+currentpoint snap M 0 - 0 Lc K ;}b/sSU{N/uW ~ |/yUP ~ |/xUP ~ |}b/sU{xUP yUP
+
+uW sLT}b/sST{N/sW ~ |/ySP ~ |/xSP ~ |}b/sT{xSP ySP sW sLT}b/sR{: + R 0 0 M}b
+
+/sRxy{: matrix astore concat 0 0 M}b/eR/; , |
+
+
+
+/mBF{@ 4 copyfont `/FontName ~ |/OrigFontType ~ |/OrigFontName ~ | 0
+
+FontMatrix idtransform ! &/PaintType known{PaintType 0 eq{/PaintType 2 |
+
+/StrokeWidth ~ |}{PaintType 1 eq PaintType 2 eq or PaintType 3 eq or &
+
+/StrokeWidth known and{StrokeWidth add/StrokeWidth ~ |}{!}?}?}{!}? @ & E
+
+definefont Pscript_Windows_Font 3 1 $ put}b/xBF{Pscript_Windows_Font ` 1 ^
+
+/FontName get 1 ^ scalefont 3 1 $ scalefont 2 copy ~ | ~ ! | E}b/xMBF{mFM
+
+astore Pscript_Windows_Font ` 1 ^/FontName get 1 ^ makefont 3 1 $ makefont 2
+
+copy ~ | ~ ! | E}b/xBF2{/sB0 ~ mBF/sB1 sB0 3 -1 $ xBF sB1}b/xMBF2{/sB0 ~ mBF
+
+mFM astore/sB1 sB0 3 -1 $ xMBF sB1}b/sB{: Pscript_Windows_Font currentfont get
+
+Ji @ S ; S}b/asB{: Pscript_Windows_Font currentfont get Ji 3 copy A ; A}b/wsB{
+
+: Pscript_Windows_Font currentfont get Ji 4 copy W ; W}b/awsB{:
+
+Pscript_Windows_Font currentfont get Ji 6 copy D ; D}b/sBT3{: @ S ; 1 1 -M S}b
+
+/asBT3{: 3 copy A ; 1 1 -M A}b/wsBT3{: 4 copy W ; 1 1 -M W}b/awsBT3{: 6 copy D
+
+; 1 1 -M D}b/mIF{iMat 4 3 -1 $ put 2 copyfont `/OrigFontType ~ |/OrigFontName
+
+~ | @ & E definefont iMat makefont Pscript_Windows_Font 3 1 $ put}b
+
+
+
+/SavedCTM null |/CTMsave{/SavedCTM SavedCTM currentmatrix |}b/CTMrestore{
+
+SavedCTM setmatrix}b/mp null |/ADO_mxRot null |/GDIHMatrix null |
+
+/GDIHPatternDict 22 dict | GDIHPatternDict `/PatternType 1 |/PaintType 2 |
+
+/Reps L2?{1}{5}? |/XStep 8 Reps mul |/YStep XStep |/BBox[0 0 XStep YStep]|
+
+/TilingType 1 |/PaintProc{` 1 Lw[]0 setdash PaintData , exec E}b/FGnd null |
+
+/BGnd null |/HS_Horizontal{horiz}b/HS_Vertical{vert}b/HS_FDiagonal{fdiag}b
+
+/HS_BDiagonal{biag}b/HS_Cross{horiz vert}b/HS_DiagCross{fdiag biag}b/MaxXYStep
+
+XStep YStep gt{XStep}{YStep}? |/horiz{Reps{0 4 M XStep 0 - 0 8 +}repeat 0 -8
+
+Reps mul + K}b/vert{Reps{4 0 M 0 YStep - 8 0 +}repeat 0 -8 Reps mul + K}b/biag
+
+{Reps{0 0 M MaxXYStep @ - 0 YStep neg M MaxXYStep @ - 0 8 +}repeat 0 -8 Reps
+
+mul + 0 YStep M 8 8 - K}b/fdiag{Reps{0 0 M MaxXYStep @ neg - 0 YStep M
+
+MaxXYStep @ neg - 0 8 +}repeat 0 -8 Reps mul + MaxXYStep @ M 8 -8 - K}b E
+
+/makehatch{GDIHPatternDict/PaintData 3 -1 $ put CTMsave GDIHMatrix setmatrix
+
+GDIHPatternDict matrix mp CTMrestore ~ U ~ 2 ^ put}b/h0{/h0/HS_Horizontal
+
+makehatch}b/h1{/h1/HS_Vertical makehatch}b/h2{/h2/HS_FDiagonal makehatch}b/h3{
+
+/h3/HS_BDiagonal makehatch}b/h4{/h4/HS_Cross makehatch}b/h5{/h5/HS_DiagCross
+
+makehatch}b/GDIBWPatternDict 17 dict @ `/PatternType 1 |/PaintType L2?{1}{2}?
+
+|/RepsV L2?{1}{6}? |/RepsH L2?{1}{5}? |/BBox[0 0 RepsH 1]|/TilingType 1 |
+
+/XStep 1 |/YStep 1 |/Height 8 RepsV mul |/Width 8 |/mx[Width 0 0 Height neg 0
+
+Height]|/FGnd null |/BGnd null |/SetBGndFGnd L2?{{BGnd null ne{BGnd aload !
+
+sgco BBox aload ! 2 ^ sub ~ 3 ^ sub ~ rf}if FGnd null ne{FGnd aload ! sgco}if}
+
+}{{}}? b/PaintProc{` SetBGndFGnd RepsH{Width Height F mx PaintData imagemask
+
+Width 0 +}repeat E}b E |/GDIBWPatternMx null |/pfprep{save 4 1 $
+
+/PatternOfTheDay 4 1 $ GDIBWPatternDict `/PaintData ~ |/BGnd ~ |/FGnd ~ | E
+
+CTMsave GDIBWPatternMx setmatrix GDIBWPatternDict matrix mp CTMrestore ~ !}b
+
+/hrf null |/prf{pfprep ~ 6 1 $ 5 hrf restore}b/GraphInit{GDIHMatrix null eq{
+
+/SavedCTM matrix | : ADO_mxRot concat 0 0 snap + : 0.48 @ GDIHPatternDict `
+
+YStep mul ~ XStep mul ~ dsnap YStep V ~ XStep V ~ E +S/GDIHMatrix matrix
+
+currentmatrix readonly | ; : 0.24 -0.24 +S GDIBWPatternDict ` Width Height E
+
+dsnap +S/GDIBWPatternMx matrix currentmatrix readonly | ; ;}if}b/cirp{360 0 An
+
+C}b/ellp{CTMsave + +S 0.5 0 M 0 0 0.5 360 0 An C CTMrestore}b/rrp{/rad ~ |/y2
+
+~ |/x2 ~ |/y1 ~ |/x1 ~ | x2 x1 add 2 V y1 M x1 y1 x1 y2 rad arct x1 y2 x2 y2
+
+rad arct x2 y2 x2 y1 rad arct x2 y1 x1 y1 rad arct C}b/RRp{CTMsave + +S/dyS ~
+
+|/dxS ~ | dxS 2 V 0 M 0 0 0 dyS 0.5 arct 0 dyS dxS dyS 0.5 arct dxS dyS dxS 0
+
+0.5 arct dxS 0 0 0 0.5 arct C CTMrestore}b
+
+
+
+L2? not g{/arct{arcto ! ! ! !}b/GDIpattfill{@ ` BGnd null ne PaintType 2 eq
+
+and{: BGnd aload ! sgco fEOFill{O}{L}? ; FGnd aload ! U/fGray 2 ^ put{2}{4}?
+
+-1 $}if E @ patterncalc : 4 ^/PaintType get 2 eq{fGray{6 -1 $ sg}{8 -3 $ sco}?
+
+}if fEOFill{eoclip}{clip}? N patternfill ; N}b/hrf{/fGray 1 ^ 6 eq | -4 $ N rp
+
+C/fEOFill F | GDIpattfill}b/hfMain{/fEOFill ~ |/fGray ~ | GDIpattfill}b/hf{T
+
+hfMain}b/hfW{F hfMain}b/hs{currentpoint strokepath M hfW}b/pfMain{/fEOFill ~ |
+
+pfprep GDIpattfill restore N}b/pf{T pfMain}b/pfW{F pfMain}b/ps{currentpoint
+
+strokepath M pfW}b/mpstr 1 string |/mp{~ @ length 12 add dict copy `
+
+/PatternCTM matrix currentmatrix |/PatternMatrix ~ |/PatWidth XStep mpstr
+
+length mul |/PatHeight YStep |/FontType 3 |/Encoding 256 array | 3 string 0 1
+
+255{Encoding ~ @ 3 ^ cvs cvn put}for !/FontMatrix matrix |/FontBBox BBox |
+
+/BuildChar{! @ ` XStep 0 FontBBox aload ! setcachedevice/PaintProc , E : exec
+
+;}b & E ~ @ 3 -1 $ definefont}b/patterncalc{` : PatternCTM setmatrix
+
+PatternMatrix concat BBox aload ! ! ! + pathbbox ; PatHeight V ceiling 4 1 $
+
+PatWidth V ceiling 4 1 $ PatHeight V floor 4 1 $ PatWidth V floor 4 1 $ 2 ^
+
+sub cvi abs ~ 3 ^ sub cvi abs ~ 4 2 $ PatHeight mul ~ PatWidth mul ~ E}b
+
+/patternfill{5 -1 $ @ ` Ji PatternCTM setmatrix PatternMatrix concat 0 2 ^ 2 ^
+
+M 0 1 mpstr length 1 sub{1 ^ mpstr 3 1 $ put}for ! 2 ^{currentpoint 5 ^{mpstr
+
+S}repeat YStep add M}repeat ! ! ! ! E}b}e
+
+
+
+L2? g{/mp/makepattern , |/hrf{6 eq setAorABC setpattern rectfill}b/hf{
+
+setAorABC setpattern O}b/hfW{setAorABC setpattern L}b/hs{setAorABC setpattern
+
+K}b/pf{pfprep setpattern O restore N}b/pfW{pfprep setpattern L restore N}b/ps{
+
+pfprep setpattern K restore N}b}e
+
+
+
+/iw 0 |/ih 0 |/im_save 0 |/s 0 |/polarity 0 |/smoothflag 0 |/mystring 0 |/bpc
+
+0 |/setup1asciiproc{[currentfile mystring/readhexstring cvx/! cvx]cvx bind}b
+
+/setup1binaryproc{[currentfile mystring/readstring cvx/! cvx]cvx bind}b
+
+/setup2asciiproc{currentfile/ASCII85Decode filter/RunLengthDecode filter}b
+
+/setup2binaryproc{currentfile/RunLengthDecode filter}b/mycolorspace{colspABC}|
+
+/myimagedict{/myimagedict 10 dict | myimagedict @ `/ImageType 1 |
+
+/MultipleDataSource F | E}b/imageprocarray[/setup1binaryproc/setup1asciiproc
+
+/setup2binaryproc/setup2asciiproc/setup1binarydecodeproc/setup1asciidecodeproc
+
+]|/L2Polarity{{[1 0]}{[0 1]}?}b/Q{/im_save save | imageprocarray ~ get/s ~ , |
+
+L2Polarity/polarity ~ |/smoothflag ~ | snap +/dx 2 ^ |/dy 1 ^ | +S/mystring ~
+
+string |/bpc ~ |/ih ~ |/iw ~ |}b/X{/im_save save | imageprocarray ~ get/s ~ ,
+
+| L2Polarity/polarity ~ |/smoothflag ~ | snap +/dx 2 ^ |/dy 1 ^ | +S/mystring
+
+~ string |/bpc ~ |/ih ~ |/iw ~ |}b/Z{im_save restore}b/Y{sgco myimagedict @ `
+
+/Width iw |/Height ih |/Decode polarity |/ImageMatrix[iw 0 0 ih 0 0]|
+
+/DataSource s |/BitsPerComponent 1 |/Interpolate smoothflag | E imagemask}b
+
+
+
+L2? not g{/setup2asciiproc{[/Level2ImagesError , aload ! T FatalErrorIf}b
+
+/setup2binaryproc/setup2asciiproc , |/L2Polarity{}|/Y{sgco iw ih polarity[iw 0
+
+0 ih 0 0]s imagemask}b}e
+
+
+
+L2? not g{/testsystemdict{where{systemdict eq{T}{F}?}{F}?}b/c 1 |/colorimage
+
+where{! T}{F}?{/c 0 statusdict `/processcolors where{! ! processcolors}{
+
+/deviceinfo where{! deviceinfo/Colors known{!{deviceinfo/Colors get}}if}if}? E
+
+| c 0 ne{/colorimage testsystemdict/setcolortransfer testsystemdict
+
+/currentcolortransfer testsystemdict/currentcmykcolor testsystemdict and and
+
+and not{/c 0 |}if}if}if c @ 1 ne ~ @ 3 ne ~ 4 ne and and{/c 0 |}if c 1 eq g{
+
+/expandbw{expandfactor mul round cvi bwclut ~ get 255 V}b/doclutimage{!/bwclut
+
+~ | bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/expandfactor ~ |[/expandbw ,/exec , @
+
+currenttransfer ~]cvx bind settransfer iw ih bpc[iw 0 0 ih 0 0]s image}b}e c @
+
+3 eq ~ 4 eq or g{/nullproc{{}}|/concatutil{/exec , 7 -1 $/exec ,}b/defsubclut{
+
+1 add getinterval |}b/spconcattransfer{/Dclut ~ |/Cclut ~ |/Bclut ~ |/Aclut ~
+
+|/ncompute ~ , | currentcolortransfer[{Aclut ncompute}concatutil]cvx[{Bclut
+
+ncompute}concatutil]cvx[{Cclut ncompute}concatutil]cvx[{Dclut ncompute}
+
+concatutil]cvx setcolortransfer}b/setuprgbcluts{/bit3x rgbclut length 3 sub |
+
+/bit1x bit3x 3 idiv |/rclut rgbclut |/gclut rclut 1 bit3x defsubclut/bclut
+
+rclut 2 bit3x defsubclut}b}e c 3 eq g{/3compute{~ bit3x mul round cvi get 255
+
+V}b/doclutimage{/rgbclut ~ | ! setuprgbcluts/3compute rclut gclut bclut @
+
+spconcattransfer iw ih bpc[iw 0 0 ih 0 0][s/exec ,/@ , @]cvx nullproc nullproc
+
+T 3 colorimage}b}e c 4 eq g{/ftoint{1 ~ sub 255 mul round cvi}b/stuffclut{
+
+cmykindex 3 -1 $ put}b/4compute{~ bit4x mul round cvi get 255 V}b
+
+/invalidcolortable? T |/computecmykclut{setuprgbcluts/bit4x rgbclut length 3
+
+idiv 4 mul 4 sub |/cmykclut bit4x 4 add string |/cclut cmykclut |/mclut cclut
+
+1 bit4x defsubclut/yclut cclut 2 bit4x defsubclut/kclut cclut 3 bit4x
+
+defsubclut/cmykindex 0 | 0 1 bit1x{@/cmykindex ~ bit1x ~ sub 4 mul | 3 mul @
+
+rclut ~ get 255 V ~ @ gclut ~ get 255 V ~ bclut ~ get 255 V setrgbcolor
+
+currentcmykcolor ftoint kclut stuffclut ftoint yclut stuffclut ftoint mclut
+
+stuffclut ftoint cclut stuffclut}for}b/doclutimage{/rgbclut ~ | !
+
+invalidcolortable?{computecmykclut}if/4compute cclut mclut yclut kclut
+
+spconcattransfer iw ih bpc[iw 0 0 ih 0 0][s/exec ,/@ , @ @]cvx nullproc
+
+nullproc nullproc T 4 colorimage}b}e c 0 eq g{/a{3 mul 3 getinterval
+
+putinterval ~ 3 add ~ 3 copy}b/8lookup/a , |/4lookup{/byte 1 ^ | -4 bitshift a
+
+byte 15 and a}b/2lookup{/byte 1 ^ | -6 bitshift a byte -4 bitshift 3 and a
+
+byte -2 bitshift 3 and a byte 3 and a}b/colorexpand{mystringexp 0 rgbclut 3
+
+copy 7 -1 $/mylookup , forall ! ! ! ! !}b/createexpandstr{/mystringexp ~
+
+mystring length mul string |}b/doclutimage{/rgbclut ~ | !/mylookup bpc 8 eq{3
+
+createexpandstr/8lookup}{bpc 4 eq{6 createexpandstr/4lookup}{12
+
+createexpandstr/2lookup}?}? , | iw ih bpc[iw 0 0 ih 0 0][s/exec ,/colorexpand
+
+,/exec ,]cvx F 3 colorimage}b}e/colorimage where{! T}{F}? g{/do24image{iw ih 8
+
+[iw 0 0 ih 0 0]s F 3 colorimage}b}DefIf_El{/rgbtogray{/str ~ |/len str length
+
+|/smlen len 3 idiv |/rstr str |/gstr str 1 len 1 sub getinterval |/bstr str 2
+
+len 2 sub getinterval | str @ 0 1 smlen 1 sub{@ 3 mul rstr 1 ^ get 0.3 mul
+
+gstr 2 ^ get 0.59 mul add bstr 3 -1 $ get 0.11 mul add round cvi put @}for ! 0
+
+smlen getinterval}b/do24image{iw ih 8[iw 0 0 ih 0 0][s/exec ,/rgbtogray ,/exec
+
+,]cvx bind image}b}e/doNimage{bpc 24 eq{do24image}{iw ih bpc[iw 0 0 ih 0 0]s
+
+image}?}b}e
+
+
+
+L2? g{/doclutimage{/rgbclut ~ | ! bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/hival ~ |[
+
+/Indexed colspABC hival rgbclut]setcolorspace myimagedict @ `/Width iw |
+
+/Height ih |/Decode[0 hival]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |
+
+/BitsPerComponent bpc |/Interpolate smoothflag | E image}b/doCMYKclutimage{
+
+/CMYKclut ~ | ! bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/hival ~ |[/Indexed/DeviceCMYK
+
+hival CMYKclut]setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode[0
+
+hival]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent bpc |
+
+/Interpolate smoothflag | E image}b/doNimage{bpc 24 eq{colspABC}{colspA}?
+
+setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode bpc 24 eq{[0 1 0 1
+
+0 1]}{[0 1]}? |/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent
+
+bpc 24 eq{8}{bpc}? |/Interpolate smoothflag | E image}b/doCMYKimage{
+
+/DeviceCMYK setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode[0 1 0
+
+1 0 1 0 1]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent 8 |
+
+/Interpolate smoothflag | E image}b}e
+
+
+
+/GreNewFont{10 dict @ 3 1 $ | @ ` 4 1 $/FontType 3 |/FontMatrix ~ |/FontBBox ~
+
+|/Encoding 256 array | 0 1 255{Encoding ~/.notdef put}for/CharProcs 257 dict |
+
+CharProcs/.notdef{}put/Metrics 257 dict | Metrics/.notdef 3 -1 $ put/BuildChar
+
+{/char ~ |/fontdict ~ |/charname fontdict/Encoding get char get | fontdict
+
+/Metrics get charname get aload ! setcachedevice fontdict ` Encoding char get
+
+CharProcs ~ get E exec}| E definefont !}|/AddChar{` Encoding 3 1 $ put
+
+CharProcs 3 1 $ put Metrics 3 1 $ put E}|
+
+
+
+/FEbuf 2 string |/FEglyph 3 string |/FE{(G00)FEglyph copy ! 1 ~{@ 16 lt{
+
+/offset 2 store}{/offset 1 store}? @ 16 FEbuf cvrs FEglyph ~ offset ~
+
+putinterval 1 ^ ~ FEglyph cvn put}for}bind |/Type1Hdr{11 dict `/FontName ~ |
+
+/PaintType ~ |/FontType 1 |/FontMatrix[1 3 ^ V 0 0 1 6 ^ V 0 0]| !/Encoding
+
+256 array 0 1 255{1 ^ ~/.notdef put}for 3 ^ 3 ^ FE | ! !/FontBBox{0 0 0 0}| &
+
+E currentfile eexec}bind |
+
+
+/pp 1 string |/ss 1 string |/rledecodebinary{/DC 0 |/BC 0 |{DC mystring length
+
+ge{exit}if currentfile ss readstring ! 0 get/BC ~ | BC 127 le{/BC BC 1 add |
+
+DC 1 DC BC add 1 sub{mystring ~ currentfile ss readstring ! 0 get put}for}{/BC
+
+257 BC sub | currentfile ss readstring ! 0 get/pp ~ | DC 1 DC BC add 1 sub{
+
+mystring ~ pp put}for}?/DC DC BC add |}loop mystring}b/rledecodeascii{/DC 0 |
+
+/BC 0 |{DC mystring length ge{exit}if currentfile ss readhexstring ! 0 get/BC
+
+~ | BC 127 le{/BC BC 1 add | DC 1 DC BC add 1 sub{mystring ~ currentfile ss
+
+readhexstring ! 0 get put}for}{/BC 257 BC sub | currentfile ss readhexstring !
+
+0 get/pp ~ | DC 1 DC BC add 1 sub{mystring ~ pp put}for}?/DC DC BC add |}loop
+
+mystring}b/setup1asciidecodeproc{[/rledecodeascii cvx]cvx bind}b
+
+/setup1binarydecodeproc{[/rledecodebinary cvx]cvx bind}b
+
+
+userdict/Pscript_Win_Compat 13 dict dup begin/bd{bind def}bind def/ld{load def
+
+}bd/CB{pop pop pop pop}bind def/B{pop pop pop pop}bind def/$x matrix def/SS{
+
+/pagesave save def}bind def/RS{/pagesave where{pop pagesave restore}{$x matrix
+
+invertmatrix concat}ifelse}bind def/ANSIVec[0/grave 1/acute 2/circumflex 3
+
+/tilde 4/macron 5/breve 6/dotaccent 7/dieresis 8/ring 9/cedilla 10
+
+/hungarumlaut 11/ogonek 12/caron 13/dotlessi 39/quotesingle 96/grave 124/bar
+
+130/quotesinglbase 131/florin 132/quotedblbase 133/ellipsis 134/dagger 135
+
+/daggerdbl 136/circumflex 137/perthousand 138/Scaron 139/guilsinglleft 140/OE
+
+145/quoteleft 146/quoteright 147/quotedblleft 148/quotedblright 149/bullet 150
+
+/endash 151/emdash 152/tilde 153/trademark 154/scaron 155/guilsinglright 156
+
+/oe 159/Ydieresis 160/space 161/exclamdown 164/currency 165/yen 166/brokenbar
+
+167/section 168/dieresis 169/copyright 170/ordfeminine 171/guillemotleft 172
+
+/logicalnot 173/hyphen 174/registered 175/macron 176/degree 177/plusminus 178
+
+/twosuperior 179/threesuperior 180/acute 181/mu 182/paragraph 183
+
+/periodcentered 184/cedilla 185/onesuperior 186/ordmasculine 187
+
+/guillemotright 188/onequarter 189/onehalf 190/threequarters 191/questiondown
+
+192/Agrave 193/Aacute 194/Acircumflex 195/Atilde 196/Adieresis 197/Aring 198
+
+/AE 199/Ccedilla 200/Egrave 201/Eacute 202/Ecircumflex 203/Edieresis 204
+
+/Igrave 205/Iacute 206/Icircumflex 207/Idieresis 208/Eth 209/Ntilde 210/Ograve
+
+211/Oacute 212/Ocircumflex 213/Otilde 214/Odieresis 215/multiply 216/Oslash
+
+217/Ugrave 218/Uacute 219/Ucircumflex 220/Udieresis 221/Yacute 222/Thorn 223
+
+/germandbls 224/agrave 225/aacute 226/acircumflex 227/atilde 228/adieresis 229
+
+/aring 230/ae 231/ccedilla 232/egrave 233/eacute 234/ecircumflex 235/edieresis
+
+236/igrave 237/iacute 238/icircumflex 239/idieresis 240/eth 241/ntilde 242
+
+/ograve 243/oacute 244/ocircumflex 245/otilde 246/odieresis 247/divide 248
+
+/oslash 249/ugrave 250/uacute 251/ucircumflex 252/udieresis 253/yacute 254
+
+/thorn 255/ydieresis]def currentdict{dup type/operatortype eq{[exch]cvx def}{
+
+pop pop}ifelse}forall/initialize{currentdict exch begin begin}bind def
+
+/terminate{/@FL where not{pop end end}{pop}ifelse}bind def/suspend/terminate
+
+load def/resume/initialize load def/M/moveto load def end put/Courier findfont
+
+10 scalefont setfont
+
+
+end /ProcSet defineresource pop
+
+
+
+
+
+
+Pscript_Win_Compat dup /initialize get exec
+
+[ 0 1.000 -1.000 0 0 0 ] false /Pscript_Win_Driver /ProcSet findresource dup /initialize get exec
+
+
+
+
+
+/mysetup [ 0.240 0 0 -0.240 7.920 592.800 ] | 
+
+
+
+
+
+
+userdict begin /pagesave save def end mysetup concat colspRefresh : 1.000 1.000 1.000 sco 0 0 2550 3300 rf ; 
+
+
+
+
+
+
+116 70 N M 1 1 rr 
+
+116 70 N M 3000 2250 rr : 1.000 1.000 1.000 sco O ; 
+
+116 70 N M 1 1 rr 
+
+116 70 N M 1 1 rr 
+
+134 87 N M 2960 2172 rr 11 Lw 0 Lc 0 Lj solid 0 0 0 sco K 
+
+455 462 N M 2600 1570 rr : 1.000 0.800 0.600 sco O ; 
+
+455 462 N M 2600 0 - 4 Lw 1 Lc 1 Lj solid 0 0 0 sco K 
+
+3055 462 N M 0 1570 - 0 0 0 sco K 
+
+3055 2032 N M -2600 0 - 0 0 0 sco K 
+
+455 2032 N M 0 -1570 - 0 0 0 sco K 
+
+455 1963 N M 40 54 rr : 1.000 1.000 0 sco O ; 0 Lc 0 Lj 0 0 0 sco K 
+
+455 1790 N M 54 54 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K 
+
+455 1613 N M 105 54 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K 
+
+455 1440 N M 115 54 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K 
+
+455 1267 N M 202 54 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K 
+
+455 1090 N M 296 54 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K 
+
+455 917 N M 411 54 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K 
+
+455 744 N M 461 54 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K 
+
+455 567 N M 1229 54 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K 
+
+455 1877 N M 65 57 rr : 0 0 1.000 sco O ; 0 0 0 sco K 
+
+455 1703 N M 97 54 rr : 0 0 1.000 sco O ; 0 0 0 sco K 
+
+455 1527 N M 151 57 rr : 0 0 1.000 sco O ; 0 0 0 sco K 
+
+455 1353 N M 155 58 rr : 0 0 1.000 sco O ; 0 0 0 sco K 
+
+455 1180 N M 393 54 rr : 0 0 1.000 sco O ; 0 0 0 sco K 
+
+455 1003 N M 440 58 rr : 0 0 1.000 sco O ; 0 0 0 sco K 
+
+455 830 N M 505 58 rr : 0 0 1.000 sco O ; 0 0 0 sco K 
+
+455 657 N M 808 54 rr : 0 0 1.000 sco O ; 0 0 0 sco K 
+
+455 480 N M 2351 58 rr : 0 0 1.000 sco O ; 0 0 0 sco K 
+
+455 462 N M 0 1570 - 1 Lc 1 Lj 0 0 0 sco K 
+
+433 2032 N M 22 0 - 0 0 0 sco K 
+
+433 1858 N M 22 0 - 0 0 0 sco K 
+
+433 1682 N M 22 0 - 0 0 0 sco K 
+
+433 1509 N M 22 0 - 0 0 0 sco K 
+
+433 1335 N M 22 0 - 0 0 0 sco K 
+
+433 1159 N M 22 0 - 0 0 0 sco K 
+
+433 985 N M 22 0 - 0 0 0 sco K 
+
+433 812 N M 22 0 - 0 0 0 sco K 
+
+433 635 N M 22 0 - 0 0 0 sco K 
+
+433 462 N M 22 0 - 0 0 0 sco K : 560 170 2116 150 rc 0.502 0 0 sco %%IncludeFont: Helvetica-Bold
+
+(F0) cvn
+
+0.931 
+
+ (Helvetica-Bold) cvn /Type1 
+
+T 
+
+(Helvetica-Bold) cvn
+
+mF 
+
+(F0_130) cvn
+
+F0
+
+130 
+
+xF 
+
+F0_130
+
+Ji 
+
+581 170 M 
+
+-3.290 0 (M)A 
+
+-0.710 0 (E)A 
+
+3.570 0 (T)A 
+
+-4.140 0 (I)A 
+
+0.290 0 (S)A 
+
+1.060 0 (')A 
+
+3.140 0 32 -3.280 0 (s )D 
+
+0.290 0 (P)A 
+
+2.720 0 (a)A 
+
+0.430 0 (r)A 
+
+-0.290 0 (t)A 
+
+-4.140 0 (i)A 
+
+0.710 0 (t)A 
+
+-4.140 0 (i)A 
+
+0.570 0 (o)A 
+
+-4.430 0 (n)A 
+
+-3.140 0 (i)A 
+
+-4.430 0 (n)A 
+
+-0.710 0 32 0.570 0 (g )D 
+
+-0.710 0 (P)A 
+
+-0.280 0 (e)A 
+
+0.430 0 (r)A 
+
+3.710 0 (f)A 
+
+-0.430 0 (o)A 
+
+0.430 0 (r)A 
+
+3.430 0 (m)A 
+
+2.720 0 (a)A 
+
+-3.430 0 (n)A 
+
+0.140 0 32 -0.280 0 (ce )D 
+
+; : 498 1959 188 55 rc 0 0 0 sco (F0_47) cvn
+
+F0
+
+47 
+
+xF 
+
+F0_47
+
+Ji 
+
+509 1959 M 
+
+-1.132 0 (1)A 
+
+1.934 0 (.)A 
+
+-1.132 0 (57)A 
+
+-4.132 0 (s)A 
+
+2.868 0 (e)A 
+
+-1.132 0 (c)A 
+
+; : 513 1786 187 55 rc 0 0 0 sco F0_47
+
+Ji 
+
+523 1786 M 
+
+-1.132 0 (2)A 
+
+1.934 0 (.)A 
+
+-1.132 0 (10)A 
+
+-4.132 0 (s)A 
+
+2.868 0 (e)A 
+
+-1.132 0 (c)A 
+
+; : 563 1610 188 55 rc 0 0 0 sco F0_47
+
+Ji 
+
+574 1610 M 
+
+-1.132 0 (4)A 
+
+1.934 0 (.)A 
+
+-1.132 0 (00)A 
+
+-4.132 0 (s)A 
+
+2.868 0 (e)A 
+
+-1.132 0 (c)A 
+
+; : 574 1436 187 55 rc 0 0 0 sco F0_47
+
+Ji 
+
+585 1436 M 
+
+-1.132 0 (4)A 
+
+1.934 0 (.)A 
+
+-1.132 0 (42)A 
+
+-4.132 0 (s)A 
+
+2.868 0 (e)A 
+
+-1.132 0 (c)A 
+
+; : 660 1263 188 55 rc 0 0 0 sco F0_47
+
+Ji 
+
+671 1263 M 
+
+-1.132 0 (7)A 
+
+1.934 0 (.)A 
+
+-1.132 0 (79)A 
+
+-4.132 0 (s)A 
+
+2.868 0 (e)A 
+
+-1.132 0 (c)A 
+
+; : 754 1086 213 55 rc 0 0 0 sco F0_47
+
+Ji 
+
+765 1086 M 
+
+-1.132 0 (11)A 
+
+1.934 0 (.)A 
+
+-1.132 0 (32)A 
+
+-4.132 0 (s)A 
+
+2.868 0 (e)A 
+
+-1.132 0 (c)A 
+
+; : 870 913 212 55 rc 0 0 0 sco F0_47
+
+Ji 
+
+880 913 M 
+
+-1.132 0 (15)A 
+
+1.934 0 (.)A 
+
+-1.132 0 (76)A 
+
+-4.132 0 (s)A 
+
+2.868 0 (e)A 
+
+-1.132 0 (c)A 
+
+; : 920 740 213 55 rc 0 0 0 sco F0_47
+
+Ji 
+
+931 740 M 
+
+-1.132 0 (17)A 
+
+1.934 0 (.)A 
+
+-1.132 0 (81)A 
+
+-4.132 0 (s)A 
+
+2.868 0 (e)A 
+
+-1.132 0 (c)A 
+
+; : 1688 563 213 55 rc 0 0 0 sco F0_47
+
+Ji 
+
+1699 563 M 
+
+-1.132 0 (47)A 
+
+1.934 0 (.)A 
+
+-1.132 0 (34)A 
+
+-4.132 0 (s)A 
+
+2.868 0 (e)A 
+
+-1.132 0 (c)A 
+
+; : 523 1873 188 55 rc 0 0 0 sco F0_47
+
+Ji 
+
+534 1873 M 
+
+-1.132 0 (2)A 
+
+1.934 0 (.)A 
+
+-1.132 0 (55)A 
+
+-4.132 0 (s)A 
+
+2.868 0 (e)A 
+
+-1.132 0 (c)A 
+
+; : 556 1700 187 55 rc 0 0 0 sco F0_47
+
+Ji 
+
+567 1700 M 
+
+-1.132 0 (3)A 
+
+1.934 0 (.)A 
+
+-1.132 0 (79)A 
+
+-4.132 0 (s)A 
+
+2.868 0 (e)A 
+
+-1.132 0 (c)A 
+
+; : 610 1527 187 55 rc 0 0 0 sco F0_47
+
+Ji 
+
+621 1527 M 
+
+-1.132 0 (5)A 
+
+1.934 0 (.)A 
+
+-1.132 0 (87)A 
+
+-4.132 0 (s)A 
+
+2.868 0 (e)A 
+
+-1.132 0 (c)A 
+
+; : 614 1353 187 55 rc 0 0 0 sco F0_47
+
+Ji 
+
+624 1353 M 
+
+-1.132 0 (5)A 
+
+1.934 0 (.)A 
+
+-1.132 0 (96)A 
+
+-4.132 0 (s)A 
+
+2.868 0 (e)A 
+
+-1.132 0 (c)A 
+
+; : 852 1177 212 55 rc 0 0 0 sco F0_47
+
+Ji 
+
+862 1177 M 
+
+-1.132 0 (15)A 
+
+1.934 0 (.)A 
+
+-1.132 0 (12)A 
+
+-4.132 0 (s)A 
+
+2.868 0 (e)A 
+
+-1.132 0 (c)A 
+
+; : 898 1000 213 55 rc 0 0 0 sco F0_47
+
+Ji 
+
+909 1000 M 
+
+-1.132 0 (16)A 
+
+1.934 0 (.)A 
+
+-1.132 0 (95)A 
+
+-4.132 0 (s)A 
+
+2.868 0 (e)A 
+
+-1.132 0 (c)A 
+
+; : 963 827 213 55 rc 0 0 0 sco F0_47
+
+Ji 
+
+974 827 M 
+
+-1.132 0 (19)A 
+
+1.934 0 (.)A 
+
+-1.132 0 (40)A 
+
+-4.132 0 (s)A 
+
+2.868 0 (e)A 
+
+-1.132 0 (c)A 
+
+; : 1266 653 213 55 rc 0 0 0 sco F0_47
+
+Ji 
+
+1277 653 M 
+
+-1.132 0 (31)A 
+
+1.934 0 (.)A 
+
+-1.132 0 (11)A 
+
+-4.132 0 (s)A 
+
+2.868 0 (e)A 
+
+-1.132 0 (c)A 
+
+; : 2809 480 213 55 rc 0 0 0 sco F0_47
+
+Ji 
+
+2820 480 M 
+
+-1.132 0 (90)A 
+
+1.934 0 (.)A 
+
+-1.132 0 (45)A 
+
+-4.132 0 (s)A 
+
+2.868 0 (e)A 
+
+-1.132 0 (c)A 
+
+; : 116 1905 3000 77 rc 0 0 0 sco %%IncludeFont: Helvetica
+
+(F3) cvn
+
+0.899 
+
+ (Helvetica) cvn /Type1 
+
+T 
+
+(Helvetica) cvn
+
+mF 
+
+(F3_69) cvn
+
+F3
+
+69 
+
+xF 
+
+F3_69
+
+Ji 
+
+188 1905 M 
+
+0.977 0 (B)A 
+
+-0.977 0 (r)A 
+
+-2.364 0 (a)A 
+
+1.500 0 (c)A 
+
+-2.500 0 (k)A 
+
+1.636 0 (2)A 
+
+; : 116 1729 3000 77 rc 0 0 0 sco F3_69
+
+Ji 
+
+199 1729 M 
+
+0.318 0 (O)A 
+
+1.500 0 (c)A 
+
+1.636 0 (e)A 
+
+-2.364 0 (an)A 
+
+; : 159 1555 2957 77 rc 0 0 0 sco F3_69
+
+Ji 
+
+282 1555 M 
+
+1.636 0 (1)A 
+
+0.636 0 (4)A 
+
+1.636 0 (4)A 
+
+; : 116 1382 3000 77 rc 0 0 0 sco F3_69
+
+Ji 
+
+181 1382 M 
+
+-3.477 0 (M)A 
+
+1.636 0 (d)A 
+
+-2.364 0 (ua)A 
+
+-1.318 0 (l)A 
+
+1.636 0 (1)A 
+
+; : 144 1205 2972 77 rc 0 0 0 sco F3_69
+
+Ji 
+
+267 1205 M 
+
+0.841 0 (T)A 
+
+-0.977 0 (r)A 
+
+1.636 0 (o)A 
+
+-1.318 0 (ll)A 
+
+; : 137 1032 2979 77 rc 0 0 0 sco F3_69
+
+Ji 
+
+260 1032 M 
+
+0.977 0 (A)A 
+
+-2.364 0 (u)A 
+
+-1.182 0 (t)A 
+
+1.636 0 (o)A 
+
+; : 116 859 3000 77 rc 0 0 0 sco F3_69
+
+Ji 
+
+181 859 M 
+
+-3.477 0 (M)A 
+
+1.636 0 (d)A 
+
+-2.364 0 (ua)A 
+
+-1.318 0 (l)A 
+
+1.636 0 (2)A 
+
+; : 177 682 2939 77 rc 0 0 0 sco F3_69
+
+Ji 
+
+300 682 M 
+
+0.977 0 (B)A 
+
+-1.318 0 (i)A 
+
+1.636 0 (g)A 
+
+; : 116 509 3000 77 rc 0 0 0 sco F3_69
+
+Ji 
+
+181 509 M 
+
+-3.477 0 (M)A 
+
+1.636 0 (d)A 
+
+-2.364 0 (ua)A 
+
+-1.318 0 (l)A 
+
+1.636 0 (3)A 
+
+; 
+
+729 2075 N M 2044 133 rr : 1.000 1.000 1.000 sco O ; 0 Lc 0 Lj 0 0 0 sco K 
+
+758 2118 N M 54 54 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K : 729 2097 2048 100 rc 0 0 0 sco (F0_87) cvn
+
+F0
+
+87 
+
+xF 
+
+F0_87
+
+Ji 
+
+837 2097 M 
+
+3.529 0 (M)A 
+
+0.814 0 (I)A 
+
+-0.029 0 (P)A 
+
+2.843 0 32 -1.029 0 (S )D 
+
+-1.814 0 (R)A 
+
+-1.372 0 (100)A 
+
+-2.372 0 (0)A 
+
+-1.372 0 (0)A 
+
+-1.825 0 (@)A 
+
+-1.372 0 (200)A 
+
+3.529 0 (M)A 
+
+-1.814 0 (H)A 
+
+-0.500 0 (z)A 
+
+; 
+
+1818 2118 N M 54 54 rr : 0 0 1.000 sco O ; 0 0 0 sco K : 1789 2097 988 100 rc 0 0 0 sco F0_87
+
+Ji 
+
+1897 2097 M 
+
+0.814 0 (I)A 
+
+0.843 0 (n)A 
+
+0.029 0 (t)A 
+
+-1.372 0 (e)A 
+
+1.000 0 32 0.814 0 (l )D 
+
+-1.029 0 (P)A 
+
+-0.029 0 (P)A 
+
+-1.814 0 (R)A 
+
+-2.686 0 (O)A 
+
+-1.825 0 (@)A 
+
+-1.372 0 (200)A 
+
+2.529 0 (M)A 
+
+-0.814 0 (H)A 
+
+-0.500 0 (z)A 
+
+; 
+
+1721 889 N M 350 42 rr : 0.502 0 0 sco O ; 
+
+1721 931 N M 350 69 rr : 0.502 0 0 sco O ; 
+
+1721 1000 N M 350 43 rr : 0.502 0 0 sco O ; 
+
+2071 889 N M 430 77 rr : 0.502 0 0 sco O ; : 1697 889 1319 1131 rc 1.000 1.000 1.000 sco %%IncludeFont: Helvetica-BoldOblique
+
+(F6) cvn
+
+0.909 
+
+ (Helvetica-BoldOblique) cvn /Type1 
+
+T 
+
+(Helvetica-BoldOblique) cvn
+
+mF 
+
+(F6_66) cvn
+
+F6
+
+66 
+
+xF 
+
+F6_66
+
+Ji 
+
+2121 891 M 
+
+0.348 0 (N)A 
+
+-0.326 0 (u)A 
+
+-0.674 0 (m)A 
+
+0.674 0 (b)A 
+
+-0.696 0 (e)A 
+
+-0.674 0 32 0.326 0 (r )D 
+
+-0.326 0 (o)A 
+
+0.022 0 (f)A 
+
+; 
+
+2071 966 N M 430 77 rr : 0.502 0 0 sco O ; : 1697 889 1319 1131 rc 1.000 1.000 1.000 sco F6_66
+
+Ji 
+
+2159 967 M 
+
+-0.022 0 (V)A 
+
+-0.696 0 (e)A 
+
+-0.674 0 (r)A 
+
+0.022 0 (t)A 
+
+0.652 0 (i)A 
+
+0.304 0 (c)A 
+
+-0.696 0 (e)A 
+
+0.304 0 (s)A 
+
+; 
+
+2501 889 N M 431 77 rr : 0.502 0 0 sco O ; : 1697 889 1319 1131 rc 1.000 1.000 1.000 sco F6_66
+
+Ji 
+
+2551 891 M 
+
+0.348 0 (N)A 
+
+-0.326 0 (u)A 
+
+-0.674 0 (m)A 
+
+0.674 0 (b)A 
+
+-0.696 0 (e)A 
+
+-0.674 0 32 0.326 0 (r )D 
+
+-0.326 0 (o)A 
+
+0.022 0 (f)A 
+
+; 
+
+2501 966 N M 431 77 rr : 0.502 0 0 sco O ; : 1697 889 1319 1131 rc 1.000 1.000 1.000 sco F6_66
+
+Ji 
+
+2618 967 M 
+
+-0.022 0 (E)A 
+
+-0.326 0 (dg)A 
+
+0.304 0 (e)A 
+
+-0.696 0 (s)A 
+
+; 
+
+1721 1047 N M 350 16 rr : 1.000 1.000 0.800 sco O ; 
+
+1721 1063 N M 350 68 rr : 1.000 1.000 0.800 sco O ; : 1697 889 1319 1131 rc 0.004 0 0 sco (F0_60) cvn
+
+F0
+
+60 
+
+xF 
+
+F0_60
+
+Ji 
+
+1738 1061 M 
+
+0.020 0 (M)A 
+
+-0.660 0 (d)A 
+
+0.340 0 (u)A 
+
+-0.360 0 (a)A 
+
+-0.680 0 (l)A 
+
+-0.360 0 (3)A 
+
+; 
+
+1721 1131 N M 350 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2071 1047 N M 430 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2071 1063 N M 430 68 rr : 1.000 1.000 0.800 sco O ; : 2071 1043 430 88 rc 0.004 0 0 sco (F3_60) cvn
+
+F3
+
+60 
+
+xF 
+
+F3_60
+
+Ji 
+
+2219 1065 M 
+
+-0.360 0 (4)A 
+
+0.320 0 (,)A 
+
+-0.360 0 (039)A 
+
+-0.680 0 (,)A 
+
+0.640 0 (1)A 
+
+-0.360 0 (60)A 
+
+; 
+
+2071 1131 N M 430 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2501 1047 N M 431 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2501 1063 N M 431 68 rr : 1.000 1.000 0.800 sco O ; : 2501 1043 431 88 rc 0.004 0 0 sco F3_60
+
+Ji 
+
+2649 1065 M 
+
+-0.360 0 (8)A 
+
+0.320 0 (,)A 
+
+-0.360 0 (016)A 
+
+-0.680 0 (,)A 
+
+0.640 0 (8)A 
+
+-0.360 0 (48)A 
+
+; 
+
+2501 1131 N M 431 16 rr : 1.000 1.000 0.800 sco O ; 
+
+1721 1043 N M 350 4 rr : 0 0 0 sco O ; : 1697 889 1319 1131 rc 
+
+1721 1043 N M 350 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+2071 1043 N M 4 4 rr : 0 0 0 sco O ; : 1697 889 1319 1131 rc 
+
+2071 1043 N M 4 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; : 1697 889 1319 1131 rc 
+
+2071 1043 N M 0 4 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+2075 1043 N M 426 4 rr : 0 0 0 sco O ; : 1697 889 1319 1131 rc 
+
+2075 1043 N M 426 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+2501 1043 N M 5 4 rr : 0 0 0 sco O ; : 1697 889 1319 1131 rc 
+
+2501 1043 N M 5 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; : 1697 889 1319 1131 rc 
+
+2501 1043 N M 0 4 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+2506 1043 N M 426 4 rr : 0 0 0 sco O ; : 1697 889 1319 1131 rc 
+
+2506 1043 N M 426 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+1721 1147 N M 350 16 rr : 1.000 1.000 0.800 sco O ; 
+
+1721 1163 N M 350 68 rr : 1.000 1.000 0.800 sco O ; : 1697 889 1319 1131 rc 0.004 0 0 sco F0_60
+
+Ji 
+
+1738 1161 M 
+
+-0.320 0 (B)A 
+
+-0.680 0 (i)A 
+
+0.340 0 (g)A 
+
+; 
+
+1721 1231 N M 350 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2071 1147 N M 430 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2071 1163 N M 430 68 rr : 1.000 1.000 0.800 sco O ; : 2071 1147 430 84 rc 0.004 0 0 sco F3_60
+
+Ji 
+
+2269 1165 M 
+
+-0.360 0 (2)A 
+
+0.640 0 (9)A 
+
+-0.360 0 (5)A 
+
+-0.680 0 (,)A 
+
+-0.360 0 (433)A 
+
+; 
+
+2071 1231 N M 430 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2501 1147 N M 431 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2501 1163 N M 431 68 rr : 1.000 1.000 0.800 sco O ; : 2501 1147 431 84 rc 0.004 0 0 sco F3_60
+
+Ji 
+
+2649 1165 M 
+
+-0.360 0 (7)A 
+
+0.320 0 (,)A 
+
+-0.360 0 (953)A 
+
+-0.680 0 (,)A 
+
+0.640 0 (4)A 
+
+-0.360 0 (53)A 
+
+; 
+
+2501 1231 N M 431 16 rr : 1.000 1.000 0.800 sco O ; 
+
+1721 1247 N M 350 16 rr : 1.000 1.000 0.800 sco O ; 
+
+1721 1263 N M 350 68 rr : 1.000 1.000 0.800 sco O ; : 1697 889 1319 1131 rc 0.004 0 0 sco F0_60
+
+Ji 
+
+1738 1261 M 
+
+0.020 0 (M)A 
+
+-0.660 0 (d)A 
+
+0.340 0 (u)A 
+
+-0.360 0 (a)A 
+
+-0.680 0 (l)A 
+
+-0.360 0 (2)A 
+
+; 
+
+1721 1331 N M 350 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2071 1247 N M 430 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2071 1263 N M 430 68 rr : 1.000 1.000 0.800 sco O ; : 2071 1247 430 84 rc 0.004 0 0 sco F3_60
+
+Ji 
+
+2219 1265 M 
+
+-0.360 0 (1)A 
+
+0.320 0 (,)A 
+
+-0.360 0 (017)A 
+
+-0.680 0 (,)A 
+
+0.640 0 (2)A 
+
+-0.360 0 (53)A 
+
+; 
+
+2071 1331 N M 430 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2501 1247 N M 431 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2501 1263 N M 431 68 rr : 1.000 1.000 0.800 sco O ; : 2501 1247 431 84 rc 0.004 0 0 sco F3_60
+
+Ji 
+
+2649 1265 M 
+
+-0.360 0 (2)A 
+
+0.320 0 (,)A 
+
+-0.360 0 (015)A 
+
+-0.680 0 (,)A 
+
+0.640 0 (7)A 
+
+-0.360 0 (14)A 
+
+; 
+
+2501 1331 N M 431 16 rr : 1.000 1.000 0.800 sco O ; 
+
+1721 1347 N M 350 16 rr : 1.000 1.000 0.800 sco O ; 
+
+1721 1363 N M 350 68 rr : 1.000 1.000 0.800 sco O ; : 1697 889 1319 1131 rc 0.004 0 0 sco F0_60
+
+Ji 
+
+1738 1361 M 
+
+-1.320 0 (A)A 
+
+-0.660 0 (u)A 
+
+0.020 0 (t)A 
+
+0.340 0 (o)A 
+
+; 
+
+1721 1431 N M 350 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2071 1347 N M 430 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2071 1363 N M 430 68 rr : 1.000 1.000 0.800 sco O ; : 2071 1347 430 84 rc 0.004 0 0 sco F3_60
+
+Ji 
+
+2269 1365 M 
+
+-0.360 0 (4)A 
+
+0.640 0 (4)A 
+
+-0.360 0 (8)A 
+
+-0.680 0 (,)A 
+
+-0.360 0 (695)A 
+
+; 
+
+2071 1431 N M 430 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2501 1347 N M 431 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2501 1363 N M 431 68 rr : 1.000 1.000 0.800 sco O ; : 2501 1347 431 84 rc 0.004 0 0 sco F3_60
+
+Ji 
+
+2649 1365 M 
+
+-0.360 0 (3)A 
+
+0.320 0 (,)A 
+
+-0.360 0 (314)A 
+
+-0.680 0 (,)A 
+
+0.640 0 (6)A 
+
+-0.360 0 (11)A 
+
+; 
+
+2501 1431 N M 431 16 rr : 1.000 1.000 0.800 sco O ; 
+
+1721 1447 N M 350 15 rr : 1.000 1.000 0.800 sco O ; 
+
+1721 1462 N M 350 69 rr : 1.000 1.000 0.800 sco O ; : 1697 889 1319 1131 rc 0.004 0 0 sco F0_60
+
+Ji 
+
+1738 1461 M 
+
+-0.660 0 (T)A 
+
+-0.340 0 (r)A 
+
+0.340 0 (o)A 
+
+-0.680 0 (l)A 
+
+0.320 0 (l)A 
+
+; 
+
+1721 1531 N M 350 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2071 1447 N M 430 15 rr : 1.000 1.000 0.800 sco O ; 
+
+2071 1462 N M 430 69 rr : 1.000 1.000 0.800 sco O ; : 2071 1447 430 84 rc 0.004 0 0 sco F3_60
+
+Ji 
+
+2269 1465 M 
+
+-0.360 0 (2)A 
+
+0.640 0 (1)A 
+
+-0.360 0 (3)A 
+
+-0.680 0 (,)A 
+
+-0.360 0 (453)A 
+
+; 
+
+2071 1531 N M 430 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2501 1447 N M 431 15 rr : 1.000 1.000 0.800 sco O ; 
+
+2501 1462 N M 431 69 rr : 1.000 1.000 0.800 sco O ; : 2501 1447 431 84 rc 0.004 0 0 sco F3_60
+
+Ji 
+
+2649 1465 M 
+
+-0.360 0 (5)A 
+
+0.320 0 (,)A 
+
+-0.360 0 (885)A 
+
+-0.680 0 (,)A 
+
+0.640 0 (8)A 
+
+-0.360 0 (29)A 
+
+; 
+
+2501 1531 N M 431 16 rr : 1.000 1.000 0.800 sco O ; 
+
+1721 1547 N M 350 15 rr : 1.000 1.000 0.800 sco O ; 
+
+1721 1562 N M 350 69 rr : 1.000 1.000 0.800 sco O ; : 1697 889 1319 1131 rc 0.004 0 0 sco F0_60
+
+Ji 
+
+1738 1561 M 
+
+0.020 0 (M)A 
+
+-0.660 0 (d)A 
+
+0.340 0 (u)A 
+
+-0.360 0 (a)A 
+
+-0.680 0 (l)A 
+
+-0.360 0 (1)A 
+
+; 
+
+1721 1631 N M 350 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2071 1547 N M 430 15 rr : 1.000 1.000 0.800 sco O ; 
+
+2071 1562 N M 430 69 rr : 1.000 1.000 0.800 sco O ; : 2071 1547 430 84 rc 0.004 0 0 sco F3_60
+
+Ji 
+
+2269 1565 M 
+
+-0.360 0 (2)A 
+
+0.640 0 (5)A 
+
+-0.360 0 (7)A 
+
+-0.680 0 (,)A 
+
+-0.360 0 (000)A 
+
+; 
+
+2071 1631 N M 430 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2501 1547 N M 431 15 rr : 1.000 1.000 0.800 sco O ; 
+
+2501 1562 N M 431 69 rr : 1.000 1.000 0.800 sco O ; : 2501 1547 431 84 rc 0.004 0 0 sco F3_60
+
+Ji 
+
+2699 1565 M 
+
+-0.360 0 (5)A 
+
+0.640 0 (0)A 
+
+-0.360 0 (5)A 
+
+-0.680 0 (,)A 
+
+-0.360 0 (048)A 
+
+; 
+
+2501 1631 N M 431 16 rr : 1.000 1.000 0.800 sco O ; 
+
+1721 1647 N M 350 15 rr : 1.000 1.000 0.800 sco O ; 
+
+1721 1662 N M 350 69 rr : 1.000 1.000 0.800 sco O ; : 1697 889 1319 1131 rc 0.004 0 0 sco F0_60
+
+Ji 
+
+1738 1661 M 
+
+-0.360 0 (1)A 
+
+0.640 0 (4)A 
+
+-0.360 0 (4)A 
+
+; 
+
+1721 1731 N M 350 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2071 1647 N M 430 15 rr : 1.000 1.000 0.800 sco O ; 
+
+2071 1662 N M 430 69 rr : 1.000 1.000 0.800 sco O ; : 2071 1647 430 84 rc 0.004 0 0 sco F3_60
+
+Ji 
+
+2269 1665 M 
+
+-0.360 0 (1)A 
+
+0.640 0 (4)A 
+
+-0.360 0 (4)A 
+
+-0.680 0 (,)A 
+
+-0.360 0 (649)A 
+
+; 
+
+2071 1731 N M 430 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2501 1647 N M 431 15 rr : 1.000 1.000 0.800 sco O ; 
+
+2501 1662 N M 431 69 rr : 1.000 1.000 0.800 sco O ; : 2501 1647 431 84 rc 0.004 0 0 sco F3_60
+
+Ji 
+
+2649 1665 M 
+
+-0.360 0 (1)A 
+
+0.320 0 (,)A 
+
+-0.360 0 (074)A 
+
+-0.680 0 (,)A 
+
+0.640 0 (3)A 
+
+-0.360 0 (93)A 
+
+; 
+
+2501 1731 N M 431 16 rr : 1.000 1.000 0.800 sco O ; 
+
+1721 1747 N M 350 15 rr : 1.000 1.000 0.800 sco O ; 
+
+1721 1762 N M 350 69 rr : 1.000 1.000 0.800 sco O ; : 1697 889 1319 1131 rc 0.004 0 0 sco F0_60
+
+Ji 
+
+1738 1761 M 
+
+-0.680 0 (O)A 
+
+-0.360 0 (ce)A 
+
+0.640 0 (a)A 
+
+-0.660 0 (n)A 
+
+; 
+
+1721 1831 N M 350 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2071 1747 N M 430 15 rr : 1.000 1.000 0.800 sco O ; 
+
+2071 1762 N M 430 69 rr : 1.000 1.000 0.800 sco O ; : 2071 1747 430 84 rc 0.004 0 0 sco F3_60
+
+Ji 
+
+2269 1765 M 
+
+-0.360 0 (1)A 
+
+0.640 0 (4)A 
+
+-0.360 0 (3)A 
+
+-0.680 0 (,)A 
+
+-0.360 0 (437)A 
+
+; 
+
+2071 1831 N M 430 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2501 1747 N M 431 15 rr : 1.000 1.000 0.800 sco O ; 
+
+2501 1762 N M 431 69 rr : 1.000 1.000 0.800 sco O ; : 2501 1747 431 84 rc 0.004 0 0 sco F3_60
+
+Ji 
+
+2699 1765 M 
+
+-0.360 0 (4)A 
+
+0.640 0 (0)A 
+
+-0.360 0 (9)A 
+
+-0.680 0 (,)A 
+
+-0.360 0 (593)A 
+
+; 
+
+2501 1831 N M 431 16 rr : 1.000 1.000 0.800 sco O ; 
+
+1721 1847 N M 350 15 rr : 1.000 1.000 0.800 sco O ; 
+
+1721 1862 N M 350 69 rr : 1.000 1.000 0.800 sco O ; : 1697 889 1319 1131 rc 0.004 0 0 sco F0_60
+
+Ji 
+
+1738 1861 M 
+
+-0.320 0 (B)A 
+
+-0.340 0 (r)A 
+
+-0.360 0 (ack)A 
+
+0.640 0 (2)A 
+
+; 
+
+1721 1931 N M 350 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2071 1847 N M 430 15 rr : 1.000 1.000 0.800 sco O ; 
+
+2071 1862 N M 430 69 rr : 1.000 1.000 0.800 sco O ; : 2071 1847 430 84 rc 0.004 0 0 sco F3_60
+
+Ji 
+
+2302 1865 M 
+
+-0.360 0 (6)A 
+
+0.640 0 (2)A 
+
+-0.680 0 (,)A 
+
+-0.360 0 (631)A 
+
+; 
+
+2071 1931 N M 430 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2501 1847 N M 431 15 rr : 1.000 1.000 0.800 sco O ; 
+
+2501 1862 N M 431 69 rr : 1.000 1.000 0.800 sco O ; : 2501 1847 431 84 rc 0.004 0 0 sco F3_60
+
+Ji 
+
+2699 1865 M 
+
+-0.360 0 (3)A 
+
+0.640 0 (6)A 
+
+-0.360 0 (6)A 
+
+-0.680 0 (,)A 
+
+-0.360 0 (559)A 
+
+; 
+
+2501 1931 N M 431 16 rr : 1.000 1.000 0.800 sco O ; 
+
+1721 1947 N M 350 5 rr : 0 0 0 sco O ; : 1697 889 1319 1131 rc 
+
+1721 1947 N M 350 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+2071 1947 N M 4 5 rr : 0 0 0 sco O ; : 1697 889 1319 1131 rc 
+
+2071 1947 N M 4 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; : 1697 889 1319 1131 rc 
+
+2071 1947 N M 0 5 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+2075 1947 N M 426 5 rr : 0 0 0 sco O ; : 1697 889 1319 1131 rc 
+
+2075 1947 N M 426 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+2501 1947 N M 5 5 rr : 0 0 0 sco O ; : 1697 889 1319 1131 rc 
+
+2501 1947 N M 5 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; : 1697 889 1319 1131 rc 
+
+2501 1947 N M 0 5 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+2506 1947 N M 426 5 rr : 0 0 0 sco O ; : 1697 889 1319 1131 rc 
+
+2506 1947 N M 426 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+LH 
+
+pagesave restore
+
+
+
+
+
+
+
+/Pscript_Win_Driver /ProcSet findresource dup /terminate get exec
+
+Pscript_Win_Compat dup /terminate get exec
+
+
+cleartomark
+countdictstack exch sub { end } repeat
+restore grestore
+%
+% End Imported PIC File: slide1.eps
+%
+% Polyline
+%
+% Begin Imported EPS File: slide2.eps
+%
+n gs
+525 9750 tr
+16.980000 -16.972921 sc
+0 -517 tr
+-39 -55 tr
+sa
+n 39 55 m 739 55 l 739 572 l 39 572 l cp clip
+countdictstack
+mark
+/showpage {} def
+% EPS file follows:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/defineresource where{pop}{userdict begin/defineresource{userdict/Resources 2
+
+copy known{get begin}{15 dict dup begin put}ifelse exch readonly exch
+
+currentdict 1 index known not{dup 30 dict def}if load 3 -1 roll 2 index put
+
+end}bind readonly def/findresource{userdict/Resources get exch get exch get}
+
+bind readonly def/resourceforall{pop pop pop pop}bind readonly def
+
+/resourcestatus{userdict/Resources 2 copy known{get exch 2 copy known{get exch
+
+known{0 -1 true}{pop pop false}ifelse}{pop pop pop false}ifelse}{pop pop false
+
+}ifelse}bind readonly def end}ifelse
+
+
+
+/Pscript_Win_Driver 200 dict dup begin
+
+
+/FatalErrorIf{{initgraphics findfont exch scalefont setfont counttomark 3 div
+
+cvi{moveto show}repeat showpage quit}{cleartomark}ifelse}bind def
+
+
+/VM? {vmstatus exch sub exch pop gt { [
+
+(This job requires more memory than is available in this printer.) 100 500
+
+(Try one or more of the following, and then print again:) 100 485
+
+(In the PostScript dialog box, click Optimize For Portability.) 115 470
+
+(In the Device Options dialog box, make sure the Available Printer Memory is accurate.) 115 455
+
+(Reduce the number of fonts in the document.) 115 440
+
+(Print the document in parts.) 115 425
+
+12 /Times-Roman showpage
+
+(%%[ PrinterError: Low Printer VM ]%%) =
+
+true FatalErrorIf}if} bind def
+
+
+/|/def load def/,/load load |/~/exch , |/?/ifelse , |/!/pop , |/`/begin , |/^
+
+/index , |/@/dup , |/+/translate , |/$/roll , |/U/userdict , |/M/moveto , |/-
+
+/rlineto , |/&/currentdict , |/:/gsave , |/;/grestore , |/F/false , |/T/true ,
+
+|/N/newpath , |/E/end , |/Ac/arc , |/An/arcn , |/A/ashow , |/D/awidthshow , |
+
+/C/closepath , |/V/div , |/O/eofill , |/L/fill , |/I/lineto , |/-C/rcurveto ,
+
+|/-M/rmoveto , |/+S/scale , |/Ji/setfont , |/Lc/setlinecap , |/Lj/setlinejoin
+
+, |/Lw/setlinewidth , |/S/show , |/LH/showpage , |/K/stroke , |/W/widthshow ,
+
+|/R/rotate , |/b{bind |}bind |/bd{bind |}bind |/xd{~ |}bd/ld{, |}bd/lw/Lw ld
+
+/lc/Lc ld/lj/Lj ld/sg/setgray ld/L2? F/languagelevel where{! languagelevel 2
+
+ge{! T}if}if |/g{@ not{U/DefIf_save save put}if U/DefIf_bool 2 ^ put}b
+
+/DefIf_El{if U/DefIf_bool get not @{U/DefIf_save get restore}if}b/e{DefIf_El !
+
+}b/self & |/reinitialize{[/TextInit/GraphInit/UtilsInit counttomark{@ where{
+
+self eq}{F}?{cvx exec}{!}?}repeat cleartomark}b/initialize{`{/ADO_mxRot ~ |
+
+/TextInitialised? F | reinitialize E}{U/Pscript_Win_Data 200 dict @ ` put
+
+/ADO_mxRot ~ |/TextInitialised? F | reinitialize}?}b/terminate{!{& self eq{
+
+exit}{E}?}loop E}b/suspend/terminate , |/resume{` Pscript_Win_Data `}b/snap{
+
+transform 0.25 sub round 0.25 add ~ 0.25 sub round 0.25 add ~ itransform}b
+
+/dsnap{dtransform round ~ round ~ idtransform}b<04>cvn{}|/setjn{{statusdict
+
+/jobname known{statusdict/jobname 3 -1 $ put}if}stopped cleartomark}b/solid{[]
+
+0 setdash}b/setdsh{0 setdash}b/colspRefresh{}b/rp{4 2 $ M 1 ^ 0 - 0 ~ - neg 0
+
+-}b/rr{1 ^ 0 - 0 ~ - neg 0 - C}b
+
+
+
+L2? not g{/rf{N rp L}b/fx{1 1 dtransform @ 0 ge{1 sub 1}{1 add -0.25}? 3 -1 $
+
+@ 0 ge{1 sub 1}{1 add -0.25}? 3 1 $ 4 1 $ idtransform 4 -2 $ idtransform}b/BZ{
+
+4 -2 $ snap + +S fx rf}b/rs{N rp C K}b/rc{N rp clip N}b/sg{setgray}b/sco{
+
+setrgbcolor}b/sgco{{sg}{sco}?}b}e
+
+
+
+L2? g{/colspA/DeviceGray |/colspABC/DeviceRGB |/setAorABC{{colspA}{colspABC}?
+
+setcolorspace}b/rf/rectfill , |/fx{1 1 dtransform @ 0 ge{1 sub 0.5}{1 add -0.5
+
+}? 3 -1 $ @ 0 ge{1 sub 0.5}{1 add -0.5}? 3 1 $ 4 1 $ idtransform 4 -2 $
+
+idtransform}b/BZ{4 -2 $ snap + +S fx rf}b/rs/rectstroke , |/rc/rectclip , |/sg
+
+{@ @ setcolor}b/sco{setcolor}b/colspRefresh{colspABC setcolorspace}b/sgco{{sg
+
+}{sco}?}b/UtilsInit{F setglobal}b/definecolorrendering{/ColorRendering
+
+defineresource !}b/findcolorrendering{@/ColorRendering resourcestatus{! !
+
+/ColorRendering findresource T}{! F}?}b/selectcolorrendering{@/ColorRendering
+
+resourcestatus{! !/ColorRendering}{!/DefaultColorRendering/ColorRendering}?
+
+findresource setcolorrendering}b}e
+
+
+
+/bullets{{/bullet}repeat}b/ANSIEncoding[/grave/acute/circumflex/tilde/macron
+
+/breve/dotaccent/dieresis/ring/cedilla/hungarumlaut/ogonek/caron/dotlessi 18
+
+bullets StandardEncoding 32 95 getinterval aload ! 3 bullets/quotesinglbase
+
+/florin/quotedblbase/ellipsis/dagger/daggerdbl/circumflex/perthousand/Scaron
+
+/guilsinglleft/OE 4 bullets/quoteleft/quoteright/quotedblleft/quotedblright
+
+/bullet/endash/emdash/tilde/trademark/scaron/guilsinglright/oe 2 bullets
+
+/Ydieresis/space/exclamdown/cent/sterling/currency/yen/brokenbar/section
+
+/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered
+
+/macron/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph
+
+/periodcentered/cedilla/onesuperior/ordmasculine/guillemotright/onequarter
+
+/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis
+
+/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute
+
+/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
+
+/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
+
+/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute
+
+/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve
+
+/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex
+
+/udieresis/yacute/thorn/ydieresis]| ANSIEncoding @ 39/quotesingle put 96/grave
+
+put/ANSIEncodingOld ANSIEncoding 256 array copy | ANSIEncodingOld @[138 153
+
+154 169 172 174 177 178 179 181 185 188 189 190 208 215 221 222 240 247 253
+
+254]{/bullet put @}forall 166/bar put 176/ring put
+
+
+
+/TextInit{TextInitialised? not{/Pscript_Windows_Font & |/TextInitialised? T |
+
+/fM[1 0 0 -1 0 0]|/mFM matrix |/iMat[1 0 0.212557 neg 1 0 0]|}if}b/xUP null |
+
+/yUP null |/uW null |/xSP null |/ySP null |/sW null |/copyfont{1 ^ length add
+
+dict `{1 ^/FID ne{|}{! !}?}forall & E}b/rF{3 copyfont @ `/Encoding
+
+ANSIEncoding &/CharStrings known{CharStrings/Eth known not{! ANSIEncodingOld}
+
+if}if | E}b/mF{findfont ~{@/Encoding get @ StandardEncoding eq{! T}{{
+
+ISOLatin1Encoding}stopped{! F}{eq}?{T}{@ ` T 32 1 127{Encoding 1 ^ get
+
+StandardEncoding 3 -1 $ get eq and}for E}?}?}{F}?{rF}{3 copyfont}? `
+
+/OrigFontType ~ |/OrigFontName ~ | & E 2 ^ ~ definefont fM 5 4 -1 $ put fM 4 0
+
+put fM makefont Pscript_Windows_Font 3 1 $ put}b/xF{scalefont
+
+Pscript_Windows_Font 3 1 $ put}b/xMF{mFM astore makefont Pscript_Windows_Font
+
+3 1 $ put}b/xF2/scalefont , |/xMF2{mFM astore makefont}b/sLT{: Lw -M
+
+currentpoint snap M 0 - 0 Lc K ;}b/sSU{N/uW ~ |/yUP ~ |/xUP ~ |}b/sU{xUP yUP
+
+uW sLT}b/sST{N/sW ~ |/ySP ~ |/xSP ~ |}b/sT{xSP ySP sW sLT}b/sR{: + R 0 0 M}b
+
+/sRxy{: matrix astore concat 0 0 M}b/eR/; , |
+
+
+
+/mBF{@ 4 copyfont `/FontName ~ |/OrigFontType ~ |/OrigFontName ~ | 0
+
+FontMatrix idtransform ! &/PaintType known{PaintType 0 eq{/PaintType 2 |
+
+/StrokeWidth ~ |}{PaintType 1 eq PaintType 2 eq or PaintType 3 eq or &
+
+/StrokeWidth known and{StrokeWidth add/StrokeWidth ~ |}{!}?}?}{!}? @ & E
+
+definefont Pscript_Windows_Font 3 1 $ put}b/xBF{Pscript_Windows_Font ` 1 ^
+
+/FontName get 1 ^ scalefont 3 1 $ scalefont 2 copy ~ | ~ ! | E}b/xMBF{mFM
+
+astore Pscript_Windows_Font ` 1 ^/FontName get 1 ^ makefont 3 1 $ makefont 2
+
+copy ~ | ~ ! | E}b/xBF2{/sB0 ~ mBF/sB1 sB0 3 -1 $ xBF sB1}b/xMBF2{/sB0 ~ mBF
+
+mFM astore/sB1 sB0 3 -1 $ xMBF sB1}b/sB{: Pscript_Windows_Font currentfont get
+
+Ji @ S ; S}b/asB{: Pscript_Windows_Font currentfont get Ji 3 copy A ; A}b/wsB{
+
+: Pscript_Windows_Font currentfont get Ji 4 copy W ; W}b/awsB{:
+
+Pscript_Windows_Font currentfont get Ji 6 copy D ; D}b/sBT3{: @ S ; 1 1 -M S}b
+
+/asBT3{: 3 copy A ; 1 1 -M A}b/wsBT3{: 4 copy W ; 1 1 -M W}b/awsBT3{: 6 copy D
+
+; 1 1 -M D}b/mIF{iMat 4 3 -1 $ put 2 copyfont `/OrigFontType ~ |/OrigFontName
+
+~ | @ & E definefont iMat makefont Pscript_Windows_Font 3 1 $ put}b
+
+
+
+/SavedCTM null |/CTMsave{/SavedCTM SavedCTM currentmatrix |}b/CTMrestore{
+
+SavedCTM setmatrix}b/mp null |/ADO_mxRot null |/GDIHMatrix null |
+
+/GDIHPatternDict 22 dict | GDIHPatternDict `/PatternType 1 |/PaintType 2 |
+
+/Reps L2?{1}{5}? |/XStep 8 Reps mul |/YStep XStep |/BBox[0 0 XStep YStep]|
+
+/TilingType 1 |/PaintProc{` 1 Lw[]0 setdash PaintData , exec E}b/FGnd null |
+
+/BGnd null |/HS_Horizontal{horiz}b/HS_Vertical{vert}b/HS_FDiagonal{fdiag}b
+
+/HS_BDiagonal{biag}b/HS_Cross{horiz vert}b/HS_DiagCross{fdiag biag}b/MaxXYStep
+
+XStep YStep gt{XStep}{YStep}? |/horiz{Reps{0 4 M XStep 0 - 0 8 +}repeat 0 -8
+
+Reps mul + K}b/vert{Reps{4 0 M 0 YStep - 8 0 +}repeat 0 -8 Reps mul + K}b/biag
+
+{Reps{0 0 M MaxXYStep @ - 0 YStep neg M MaxXYStep @ - 0 8 +}repeat 0 -8 Reps
+
+mul + 0 YStep M 8 8 - K}b/fdiag{Reps{0 0 M MaxXYStep @ neg - 0 YStep M
+
+MaxXYStep @ neg - 0 8 +}repeat 0 -8 Reps mul + MaxXYStep @ M 8 -8 - K}b E
+
+/makehatch{GDIHPatternDict/PaintData 3 -1 $ put CTMsave GDIHMatrix setmatrix
+
+GDIHPatternDict matrix mp CTMrestore ~ U ~ 2 ^ put}b/h0{/h0/HS_Horizontal
+
+makehatch}b/h1{/h1/HS_Vertical makehatch}b/h2{/h2/HS_FDiagonal makehatch}b/h3{
+
+/h3/HS_BDiagonal makehatch}b/h4{/h4/HS_Cross makehatch}b/h5{/h5/HS_DiagCross
+
+makehatch}b/GDIBWPatternDict 17 dict @ `/PatternType 1 |/PaintType L2?{1}{2}?
+
+|/RepsV L2?{1}{6}? |/RepsH L2?{1}{5}? |/BBox[0 0 RepsH 1]|/TilingType 1 |
+
+/XStep 1 |/YStep 1 |/Height 8 RepsV mul |/Width 8 |/mx[Width 0 0 Height neg 0
+
+Height]|/FGnd null |/BGnd null |/SetBGndFGnd L2?{{BGnd null ne{BGnd aload !
+
+sgco BBox aload ! 2 ^ sub ~ 3 ^ sub ~ rf}if FGnd null ne{FGnd aload ! sgco}if}
+
+}{{}}? b/PaintProc{` SetBGndFGnd RepsH{Width Height F mx PaintData imagemask
+
+Width 0 +}repeat E}b E |/GDIBWPatternMx null |/pfprep{save 4 1 $
+
+/PatternOfTheDay 4 1 $ GDIBWPatternDict `/PaintData ~ |/BGnd ~ |/FGnd ~ | E
+
+CTMsave GDIBWPatternMx setmatrix GDIBWPatternDict matrix mp CTMrestore ~ !}b
+
+/hrf null |/prf{pfprep ~ 6 1 $ 5 hrf restore}b/GraphInit{GDIHMatrix null eq{
+
+/SavedCTM matrix | : ADO_mxRot concat 0 0 snap + : 0.48 @ GDIHPatternDict `
+
+YStep mul ~ XStep mul ~ dsnap YStep V ~ XStep V ~ E +S/GDIHMatrix matrix
+
+currentmatrix readonly | ; : 0.24 -0.24 +S GDIBWPatternDict ` Width Height E
+
+dsnap +S/GDIBWPatternMx matrix currentmatrix readonly | ; ;}if}b/cirp{360 0 An
+
+C}b/ellp{CTMsave + +S 0.5 0 M 0 0 0.5 360 0 An C CTMrestore}b/rrp{/rad ~ |/y2
+
+~ |/x2 ~ |/y1 ~ |/x1 ~ | x2 x1 add 2 V y1 M x1 y1 x1 y2 rad arct x1 y2 x2 y2
+
+rad arct x2 y2 x2 y1 rad arct x2 y1 x1 y1 rad arct C}b/RRp{CTMsave + +S/dyS ~
+
+|/dxS ~ | dxS 2 V 0 M 0 0 0 dyS 0.5 arct 0 dyS dxS dyS 0.5 arct dxS dyS dxS 0
+
+0.5 arct dxS 0 0 0 0.5 arct C CTMrestore}b
+
+
+
+L2? not g{/arct{arcto ! ! ! !}b/GDIpattfill{@ ` BGnd null ne PaintType 2 eq
+
+and{: BGnd aload ! sgco fEOFill{O}{L}? ; FGnd aload ! U/fGray 2 ^ put{2}{4}?
+
+-1 $}if E @ patterncalc : 4 ^/PaintType get 2 eq{fGray{6 -1 $ sg}{8 -3 $ sco}?
+
+}if fEOFill{eoclip}{clip}? N patternfill ; N}b/hrf{/fGray 1 ^ 6 eq | -4 $ N rp
+
+C/fEOFill F | GDIpattfill}b/hfMain{/fEOFill ~ |/fGray ~ | GDIpattfill}b/hf{T
+
+hfMain}b/hfW{F hfMain}b/hs{currentpoint strokepath M hfW}b/pfMain{/fEOFill ~ |
+
+pfprep GDIpattfill restore N}b/pf{T pfMain}b/pfW{F pfMain}b/ps{currentpoint
+
+strokepath M pfW}b/mpstr 1 string |/mp{~ @ length 12 add dict copy `
+
+/PatternCTM matrix currentmatrix |/PatternMatrix ~ |/PatWidth XStep mpstr
+
+length mul |/PatHeight YStep |/FontType 3 |/Encoding 256 array | 3 string 0 1
+
+255{Encoding ~ @ 3 ^ cvs cvn put}for !/FontMatrix matrix |/FontBBox BBox |
+
+/BuildChar{! @ ` XStep 0 FontBBox aload ! setcachedevice/PaintProc , E : exec
+
+;}b & E ~ @ 3 -1 $ definefont}b/patterncalc{` : PatternCTM setmatrix
+
+PatternMatrix concat BBox aload ! ! ! + pathbbox ; PatHeight V ceiling 4 1 $
+
+PatWidth V ceiling 4 1 $ PatHeight V floor 4 1 $ PatWidth V floor 4 1 $ 2 ^
+
+sub cvi abs ~ 3 ^ sub cvi abs ~ 4 2 $ PatHeight mul ~ PatWidth mul ~ E}b
+
+/patternfill{5 -1 $ @ ` Ji PatternCTM setmatrix PatternMatrix concat 0 2 ^ 2 ^
+
+M 0 1 mpstr length 1 sub{1 ^ mpstr 3 1 $ put}for ! 2 ^{currentpoint 5 ^{mpstr
+
+S}repeat YStep add M}repeat ! ! ! ! E}b}e
+
+
+
+L2? g{/mp/makepattern , |/hrf{6 eq setAorABC setpattern rectfill}b/hf{
+
+setAorABC setpattern O}b/hfW{setAorABC setpattern L}b/hs{setAorABC setpattern
+
+K}b/pf{pfprep setpattern O restore N}b/pfW{pfprep setpattern L restore N}b/ps{
+
+pfprep setpattern K restore N}b}e
+
+
+
+/iw 0 |/ih 0 |/im_save 0 |/s 0 |/polarity 0 |/smoothflag 0 |/mystring 0 |/bpc
+
+0 |/setup1asciiproc{[currentfile mystring/readhexstring cvx/! cvx]cvx bind}b
+
+/setup1binaryproc{[currentfile mystring/readstring cvx/! cvx]cvx bind}b
+
+/setup2asciiproc{currentfile/ASCII85Decode filter/RunLengthDecode filter}b
+
+/setup2binaryproc{currentfile/RunLengthDecode filter}b/mycolorspace{colspABC}|
+
+/myimagedict{/myimagedict 10 dict | myimagedict @ `/ImageType 1 |
+
+/MultipleDataSource F | E}b/imageprocarray[/setup1binaryproc/setup1asciiproc
+
+/setup2binaryproc/setup2asciiproc/setup1binarydecodeproc/setup1asciidecodeproc
+
+]|/L2Polarity{{[1 0]}{[0 1]}?}b/Q{/im_save save | imageprocarray ~ get/s ~ , |
+
+L2Polarity/polarity ~ |/smoothflag ~ | snap +/dx 2 ^ |/dy 1 ^ | +S/mystring ~
+
+string |/bpc ~ |/ih ~ |/iw ~ |}b/X{/im_save save | imageprocarray ~ get/s ~ ,
+
+| L2Polarity/polarity ~ |/smoothflag ~ | snap +/dx 2 ^ |/dy 1 ^ | +S/mystring
+
+~ string |/bpc ~ |/ih ~ |/iw ~ |}b/Z{im_save restore}b/Y{sgco myimagedict @ `
+
+/Width iw |/Height ih |/Decode polarity |/ImageMatrix[iw 0 0 ih 0 0]|
+
+/DataSource s |/BitsPerComponent 1 |/Interpolate smoothflag | E imagemask}b
+
+
+
+L2? not g{/setup2asciiproc{[/Level2ImagesError , aload ! T FatalErrorIf}b
+
+/setup2binaryproc/setup2asciiproc , |/L2Polarity{}|/Y{sgco iw ih polarity[iw 0
+
+0 ih 0 0]s imagemask}b}e
+
+
+
+L2? not g{/testsystemdict{where{systemdict eq{T}{F}?}{F}?}b/c 1 |/colorimage
+
+where{! T}{F}?{/c 0 statusdict `/processcolors where{! ! processcolors}{
+
+/deviceinfo where{! deviceinfo/Colors known{!{deviceinfo/Colors get}}if}if}? E
+
+| c 0 ne{/colorimage testsystemdict/setcolortransfer testsystemdict
+
+/currentcolortransfer testsystemdict/currentcmykcolor testsystemdict and and
+
+and not{/c 0 |}if}if}if c @ 1 ne ~ @ 3 ne ~ 4 ne and and{/c 0 |}if c 1 eq g{
+
+/expandbw{expandfactor mul round cvi bwclut ~ get 255 V}b/doclutimage{!/bwclut
+
+~ | bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/expandfactor ~ |[/expandbw ,/exec , @
+
+currenttransfer ~]cvx bind settransfer iw ih bpc[iw 0 0 ih 0 0]s image}b}e c @
+
+3 eq ~ 4 eq or g{/nullproc{{}}|/concatutil{/exec , 7 -1 $/exec ,}b/defsubclut{
+
+1 add getinterval |}b/spconcattransfer{/Dclut ~ |/Cclut ~ |/Bclut ~ |/Aclut ~
+
+|/ncompute ~ , | currentcolortransfer[{Aclut ncompute}concatutil]cvx[{Bclut
+
+ncompute}concatutil]cvx[{Cclut ncompute}concatutil]cvx[{Dclut ncompute}
+
+concatutil]cvx setcolortransfer}b/setuprgbcluts{/bit3x rgbclut length 3 sub |
+
+/bit1x bit3x 3 idiv |/rclut rgbclut |/gclut rclut 1 bit3x defsubclut/bclut
+
+rclut 2 bit3x defsubclut}b}e c 3 eq g{/3compute{~ bit3x mul round cvi get 255
+
+V}b/doclutimage{/rgbclut ~ | ! setuprgbcluts/3compute rclut gclut bclut @
+
+spconcattransfer iw ih bpc[iw 0 0 ih 0 0][s/exec ,/@ , @]cvx nullproc nullproc
+
+T 3 colorimage}b}e c 4 eq g{/ftoint{1 ~ sub 255 mul round cvi}b/stuffclut{
+
+cmykindex 3 -1 $ put}b/4compute{~ bit4x mul round cvi get 255 V}b
+
+/invalidcolortable? T |/computecmykclut{setuprgbcluts/bit4x rgbclut length 3
+
+idiv 4 mul 4 sub |/cmykclut bit4x 4 add string |/cclut cmykclut |/mclut cclut
+
+1 bit4x defsubclut/yclut cclut 2 bit4x defsubclut/kclut cclut 3 bit4x
+
+defsubclut/cmykindex 0 | 0 1 bit1x{@/cmykindex ~ bit1x ~ sub 4 mul | 3 mul @
+
+rclut ~ get 255 V ~ @ gclut ~ get 255 V ~ bclut ~ get 255 V setrgbcolor
+
+currentcmykcolor ftoint kclut stuffclut ftoint yclut stuffclut ftoint mclut
+
+stuffclut ftoint cclut stuffclut}for}b/doclutimage{/rgbclut ~ | !
+
+invalidcolortable?{computecmykclut}if/4compute cclut mclut yclut kclut
+
+spconcattransfer iw ih bpc[iw 0 0 ih 0 0][s/exec ,/@ , @ @]cvx nullproc
+
+nullproc nullproc T 4 colorimage}b}e c 0 eq g{/a{3 mul 3 getinterval
+
+putinterval ~ 3 add ~ 3 copy}b/8lookup/a , |/4lookup{/byte 1 ^ | -4 bitshift a
+
+byte 15 and a}b/2lookup{/byte 1 ^ | -6 bitshift a byte -4 bitshift 3 and a
+
+byte -2 bitshift 3 and a byte 3 and a}b/colorexpand{mystringexp 0 rgbclut 3
+
+copy 7 -1 $/mylookup , forall ! ! ! ! !}b/createexpandstr{/mystringexp ~
+
+mystring length mul string |}b/doclutimage{/rgbclut ~ | !/mylookup bpc 8 eq{3
+
+createexpandstr/8lookup}{bpc 4 eq{6 createexpandstr/4lookup}{12
+
+createexpandstr/2lookup}?}? , | iw ih bpc[iw 0 0 ih 0 0][s/exec ,/colorexpand
+
+,/exec ,]cvx F 3 colorimage}b}e/colorimage where{! T}{F}? g{/do24image{iw ih 8
+
+[iw 0 0 ih 0 0]s F 3 colorimage}b}DefIf_El{/rgbtogray{/str ~ |/len str length
+
+|/smlen len 3 idiv |/rstr str |/gstr str 1 len 1 sub getinterval |/bstr str 2
+
+len 2 sub getinterval | str @ 0 1 smlen 1 sub{@ 3 mul rstr 1 ^ get 0.3 mul
+
+gstr 2 ^ get 0.59 mul add bstr 3 -1 $ get 0.11 mul add round cvi put @}for ! 0
+
+smlen getinterval}b/do24image{iw ih 8[iw 0 0 ih 0 0][s/exec ,/rgbtogray ,/exec
+
+,]cvx bind image}b}e/doNimage{bpc 24 eq{do24image}{iw ih bpc[iw 0 0 ih 0 0]s
+
+image}?}b}e
+
+
+
+L2? g{/doclutimage{/rgbclut ~ | ! bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/hival ~ |[
+
+/Indexed colspABC hival rgbclut]setcolorspace myimagedict @ `/Width iw |
+
+/Height ih |/Decode[0 hival]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |
+
+/BitsPerComponent bpc |/Interpolate smoothflag | E image}b/doCMYKclutimage{
+
+/CMYKclut ~ | ! bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/hival ~ |[/Indexed/DeviceCMYK
+
+hival CMYKclut]setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode[0
+
+hival]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent bpc |
+
+/Interpolate smoothflag | E image}b/doNimage{bpc 24 eq{colspABC}{colspA}?
+
+setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode bpc 24 eq{[0 1 0 1
+
+0 1]}{[0 1]}? |/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent
+
+bpc 24 eq{8}{bpc}? |/Interpolate smoothflag | E image}b/doCMYKimage{
+
+/DeviceCMYK setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode[0 1 0
+
+1 0 1 0 1]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent 8 |
+
+/Interpolate smoothflag | E image}b}e
+
+
+
+/GreNewFont{10 dict @ 3 1 $ | @ ` 4 1 $/FontType 3 |/FontMatrix ~ |/FontBBox ~
+
+|/Encoding 256 array | 0 1 255{Encoding ~/.notdef put}for/CharProcs 257 dict |
+
+CharProcs/.notdef{}put/Metrics 257 dict | Metrics/.notdef 3 -1 $ put/BuildChar
+
+{/char ~ |/fontdict ~ |/charname fontdict/Encoding get char get | fontdict
+
+/Metrics get charname get aload ! setcachedevice fontdict ` Encoding char get
+
+CharProcs ~ get E exec}| E definefont !}|/AddChar{` Encoding 3 1 $ put
+
+CharProcs 3 1 $ put Metrics 3 1 $ put E}|
+
+
+
+/FEbuf 2 string |/FEglyph 3 string |/FE{(G00)FEglyph copy ! 1 ~{@ 16 lt{
+
+/offset 2 store}{/offset 1 store}? @ 16 FEbuf cvrs FEglyph ~ offset ~
+
+putinterval 1 ^ ~ FEglyph cvn put}for}bind |/Type1Hdr{11 dict `/FontName ~ |
+
+/PaintType ~ |/FontType 1 |/FontMatrix[1 3 ^ V 0 0 1 6 ^ V 0 0]| !/Encoding
+
+256 array 0 1 255{1 ^ ~/.notdef put}for 3 ^ 3 ^ FE | ! !/FontBBox{0 0 0 0}| &
+
+E currentfile eexec}bind |
+
+
+/pp 1 string |/ss 1 string |/rledecodebinary{/DC 0 |/BC 0 |{DC mystring length
+
+ge{exit}if currentfile ss readstring ! 0 get/BC ~ | BC 127 le{/BC BC 1 add |
+
+DC 1 DC BC add 1 sub{mystring ~ currentfile ss readstring ! 0 get put}for}{/BC
+
+257 BC sub | currentfile ss readstring ! 0 get/pp ~ | DC 1 DC BC add 1 sub{
+
+mystring ~ pp put}for}?/DC DC BC add |}loop mystring}b/rledecodeascii{/DC 0 |
+
+/BC 0 |{DC mystring length ge{exit}if currentfile ss readhexstring ! 0 get/BC
+
+~ | BC 127 le{/BC BC 1 add | DC 1 DC BC add 1 sub{mystring ~ currentfile ss
+
+readhexstring ! 0 get put}for}{/BC 257 BC sub | currentfile ss readhexstring !
+
+0 get/pp ~ | DC 1 DC BC add 1 sub{mystring ~ pp put}for}?/DC DC BC add |}loop
+
+mystring}b/setup1asciidecodeproc{[/rledecodeascii cvx]cvx bind}b
+
+/setup1binarydecodeproc{[/rledecodebinary cvx]cvx bind}b
+
+
+userdict/Pscript_Win_Compat 13 dict dup begin/bd{bind def}bind def/ld{load def
+
+}bd/CB{pop pop pop pop}bind def/B{pop pop pop pop}bind def/$x matrix def/SS{
+
+/pagesave save def}bind def/RS{/pagesave where{pop pagesave restore}{$x matrix
+
+invertmatrix concat}ifelse}bind def/ANSIVec[0/grave 1/acute 2/circumflex 3
+
+/tilde 4/macron 5/breve 6/dotaccent 7/dieresis 8/ring 9/cedilla 10
+
+/hungarumlaut 11/ogonek 12/caron 13/dotlessi 39/quotesingle 96/grave 124/bar
+
+130/quotesinglbase 131/florin 132/quotedblbase 133/ellipsis 134/dagger 135
+
+/daggerdbl 136/circumflex 137/perthousand 138/Scaron 139/guilsinglleft 140/OE
+
+145/quoteleft 146/quoteright 147/quotedblleft 148/quotedblright 149/bullet 150
+
+/endash 151/emdash 152/tilde 153/trademark 154/scaron 155/guilsinglright 156
+
+/oe 159/Ydieresis 160/space 161/exclamdown 164/currency 165/yen 166/brokenbar
+
+167/section 168/dieresis 169/copyright 170/ordfeminine 171/guillemotleft 172
+
+/logicalnot 173/hyphen 174/registered 175/macron 176/degree 177/plusminus 178
+
+/twosuperior 179/threesuperior 180/acute 181/mu 182/paragraph 183
+
+/periodcentered 184/cedilla 185/onesuperior 186/ordmasculine 187
+
+/guillemotright 188/onequarter 189/onehalf 190/threequarters 191/questiondown
+
+192/Agrave 193/Aacute 194/Acircumflex 195/Atilde 196/Adieresis 197/Aring 198
+
+/AE 199/Ccedilla 200/Egrave 201/Eacute 202/Ecircumflex 203/Edieresis 204
+
+/Igrave 205/Iacute 206/Icircumflex 207/Idieresis 208/Eth 209/Ntilde 210/Ograve
+
+211/Oacute 212/Ocircumflex 213/Otilde 214/Odieresis 215/multiply 216/Oslash
+
+217/Ugrave 218/Uacute 219/Ucircumflex 220/Udieresis 221/Yacute 222/Thorn 223
+
+/germandbls 224/agrave 225/aacute 226/acircumflex 227/atilde 228/adieresis 229
+
+/aring 230/ae 231/ccedilla 232/egrave 233/eacute 234/ecircumflex 235/edieresis
+
+236/igrave 237/iacute 238/icircumflex 239/idieresis 240/eth 241/ntilde 242
+
+/ograve 243/oacute 244/ocircumflex 245/otilde 246/odieresis 247/divide 248
+
+/oslash 249/ugrave 250/uacute 251/ucircumflex 252/udieresis 253/yacute 254
+
+/thorn 255/ydieresis]def currentdict{dup type/operatortype eq{[exch]cvx def}{
+
+pop pop}ifelse}forall/initialize{currentdict exch begin begin}bind def
+
+/terminate{/@FL where not{pop end end}{pop}ifelse}bind def/suspend/terminate
+
+load def/resume/initialize load def/M/moveto load def end put/Courier findfont
+
+10 scalefont setfont
+
+
+end /ProcSet defineresource pop
+
+
+
+
+
+
+Pscript_Win_Compat dup /initialize get exec
+
+[ 0 1.000 -1.000 0 0 0 ] false /Pscript_Win_Driver /ProcSet findresource dup /initialize get exec
+
+
+
+
+
+/mysetup [ 0.240 0 0 -0.240 7.920 592.800 ] | 
+
+
+
+
+
+
+userdict begin /pagesave save def end mysetup concat colspRefresh : 1.000 1.000 1.000 sco 0 0 2550 3300 rf ; 
+
+
+
+
+
+
+116 70 N M 1 1 rr 
+
+116 70 N M 3000 2250 rr : 1.000 1.000 1.000 sco O ; 
+
+116 70 N M 1 1 rr 
+
+116 70 N M 1 1 rr 
+
+133 87 N M 2904 2146 rr 10 Lw 0 Lc 0 Lj solid 0 0 0 sco K 
+
+579 456 N M 2416 1561 rr : 1.000 0.800 0.600 sco O ; 
+
+579 456 N M 2416 0 - 3 Lw 1 Lc 1 Lj solid 0 0 0 sco K 
+
+2995 456 N M 0 1561 - 0 0 0 sco K 
+
+2995 2017 N M -2416 0 - 0 0 0 sco K 
+
+579 2017 N M 0 -1561 - 0 0 0 sco K 
+
+579 1947 N M 73 56 rr : 1.000 1.000 0 sco O ; 0 Lc 0 Lj 0 0 0 sco K 
+
+579 1774 N M 177 55 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K 
+
+579 1600 N M 215 55 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K 
+
+579 1426 N M 274 56 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K 
+
+579 1252 N M 285 56 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K 
+
+579 1082 N M 319 55 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K 
+
+579 908 N M 476 56 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K 
+
+579 734 N M 845 56 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K 
+
+579 560 N M 1074 56 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K 
+
+579 1864 N M 121 52 rr : 0 0 1.000 sco O ; 0 0 0 sco K 
+
+579 1690 N M 319 52 rr : 0 0 1.000 sco O ; 0 0 0 sco K 
+
+579 1516 N M 274 53 rr : 0 0 1.000 sco O ; 0 0 0 sco K 
+
+579 1343 N M 330 52 rr : 0 0 1.000 sco O ; 0 0 0 sco K 
+
+579 1169 N M 532 55 rr : 0 0 1.000 sco O ; 0 0 0 sco K 
+
+579 998 N M 528 52 rr : 0 0 1.000 sco O ; 0 0 0 sco K 
+
+579 824 N M 911 53 rr : 0 0 1.000 sco O ; 0 0 0 sco K 
+
+579 651 N M 1617 52 rr : 0 0 1.000 sco O ; 0 0 0 sco K 
+
+579 477 N M 1968 52 rr : 0 0 1.000 sco O ; 0 0 0 sco K 
+
+579 456 N M 0 1561 - 1 Lc 1 Lj 0 0 0 sco K 
+
+558 2017 N M 21 0 - 0 0 0 sco K 
+
+558 1843 N M 21 0 - 0 0 0 sco K 
+
+558 1669 N M 21 0 - 0 0 0 sco K 
+
+558 1495 N M 21 0 - 0 0 0 sco K 
+
+558 1322 N M 21 0 - 0 0 0 sco K 
+
+558 1151 N M 21 0 - 0 0 0 sco K 
+
+558 977 N M 21 0 - 0 0 0 sco K 
+
+558 804 N M 21 0 - 0 0 0 sco K 
+
+558 630 N M 21 0 - 0 0 0 sco K 
+
+558 456 N M 21 0 - 0 0 0 sco K : 610 167 1954 149 rc 0.502 0 0 sco %%IncludeFont: Helvetica-Bold
+
+(F0) cvn
+
+0.930 
+
+ (Helvetica-Bold) cvn /Type1 
+
+T 
+
+(Helvetica-Bold) cvn
+
+mF 
+
+(F0_129) cvn
+
+F0
+
+129 
+
+xF 
+
+F0_129
+
+Ji 
+
+634 167 M 
+
+0.543 0 (M)A 
+
+0.957 0 (E)A 
+
+1.181 0 (T)A 
+
+-4.862 0 (I)A 
+
+0.957 0 (S)A 
+
+0.298 0 (')A 
+
+-2.138 0 32 1.276 0 (s )D 
+
+0.638 0 (O)A 
+
+-1.181 0 (r)A 
+
+1.181 0 (d)A 
+
+1.276 0 (e)A 
+
+-2.181 0 (r)A 
+
+-0.862 0 (i)A 
+
+-2.043 0 32 1.181 0 (ng )D 
+
+0.957 0 (P)A 
+
+1.276 0 (e)A 
+
+-2.181 0 (r)A 
+
+-0.957 0 (f)A 
+
+1.181 0 (o)A 
+
+-1.181 0 (r)A 
+
+0.319 0 (m)A 
+
+1.276 0 (a)A 
+
+1.181 0 (n)A 
+
+-3.138 0 32 1.276 0 (ce )D 
+
+; : 655 1947 181 53 rc 0 0 0 sco (F0_45) cvn
+
+F0
+
+45 
+
+xF 
+
+F0_45
+
+Ji 
+
+665 1947 M 
+
+-1.020 0 (0)A 
+
+1.490 0 (.)A 
+
+-0.020 0 (9)A 
+
+-1.020 0 (0)A 
+
+-4.020 0 (s)A 
+
+2.980 0 (e)A 
+
+-1.020 0 (c)A 
+
+; : 759 1774 181 53 rc 0 0 0 sco F0_45
+
+Ji 
+
+770 1774 M 
+
+-1.020 0 (2)A 
+
+1.490 0 (.)A 
+
+-0.020 0 (1)A 
+
+-1.020 0 (9)A 
+
+-4.020 0 (s)A 
+
+2.980 0 (e)A 
+
+-1.020 0 (c)A 
+
+; : 798 1600 180 53 rc 0 0 0 sco F0_45
+
+Ji 
+
+808 1600 M 
+
+-1.020 0 (2)A 
+
+1.490 0 (.)A 
+
+-0.020 0 (6)A 
+
+-1.020 0 (7)A 
+
+-4.020 0 (s)A 
+
+2.980 0 (e)A 
+
+-1.020 0 (c)A 
+
+; : 857 1426 181 53 rc 0 0 0 sco F0_45
+
+Ji 
+
+867 1426 M 
+
+-1.020 0 (3)A 
+
+1.490 0 (.)A 
+
+-0.020 0 (4)A 
+
+-1.020 0 (3)A 
+
+-4.020 0 (s)A 
+
+2.980 0 (e)A 
+
+-1.020 0 (c)A 
+
+; : 867 1252 181 53 rc 0 0 0 sco F0_45
+
+Ji 
+
+878 1252 M 
+
+-1.020 0 (3)A 
+
+1.490 0 (.)A 
+
+-0.020 0 (5)A 
+
+-1.020 0 (5)A 
+
+-4.020 0 (s)A 
+
+2.980 0 (e)A 
+
+-1.020 0 (c)A 
+
+; : 902 1078 181 53 rc 0 0 0 sco F0_45
+
+Ji 
+
+912 1078 M 
+
+-1.020 0 (3)A 
+
+1.490 0 (.)A 
+
+-0.020 0 (9)A 
+
+-1.020 0 (6)A 
+
+-4.020 0 (s)A 
+
+2.980 0 (e)A 
+
+-1.020 0 (c)A 
+
+; : 1058 904 181 53 rc 0 0 0 sco F0_45
+
+Ji 
+
+1069 904 M 
+
+-1.020 0 (5)A 
+
+1.490 0 (.)A 
+
+-0.020 0 (9)A 
+
+-1.020 0 (0)A 
+
+-4.020 0 (s)A 
+
+2.980 0 (e)A 
+
+-1.020 0 (c)A 
+
+; : 1427 731 205 53 rc 0 0 0 sco F0_45
+
+Ji 
+
+1437 731 M 
+
+-1.020 0 (1)A 
+
+-0.020 0 (0)A 
+
+1.490 0 (.)A 
+
+-1.020 0 (51)A 
+
+-4.020 0 (s)A 
+
+2.980 0 (e)A 
+
+-1.020 0 (c)A 
+
+; : 1657 557 205 53 rc 0 0 0 sco F0_45
+
+Ji 
+
+1667 557 M 
+
+-1.020 0 (1)A 
+
+-0.020 0 (3)A 
+
+1.490 0 (.)A 
+
+-1.020 0 (34)A 
+
+-4.020 0 (s)A 
+
+2.980 0 (e)A 
+
+-1.020 0 (c)A 
+
+; : 704 1861 181 53 rc 0 0 0 sco F0_45
+
+Ji 
+
+714 1861 M 
+
+-1.020 0 (1)A 
+
+1.490 0 (.)A 
+
+-0.020 0 (5)A 
+
+-1.020 0 (2)A 
+
+-4.020 0 (s)A 
+
+2.980 0 (e)A 
+
+-1.020 0 (c)A 
+
+; : 902 1687 181 53 rc 0 0 0 sco F0_45
+
+Ji 
+
+912 1687 M 
+
+-1.020 0 (3)A 
+
+1.490 0 (.)A 
+
+-0.020 0 (9)A 
+
+-1.020 0 (5)A 
+
+-4.020 0 (s)A 
+
+2.980 0 (e)A 
+
+-1.020 0 (c)A 
+
+; : 857 1513 181 53 rc 0 0 0 sco F0_45
+
+Ji 
+
+867 1513 M 
+
+-1.020 0 (3)A 
+
+1.490 0 (.)A 
+
+-0.020 0 (4)A 
+
+-1.020 0 (2)A 
+
+-4.020 0 (s)A 
+
+2.980 0 (e)A 
+
+-1.020 0 (c)A 
+
+; : 912 1339 181 53 rc 0 0 0 sco F0_45
+
+Ji 
+
+923 1339 M 
+
+-1.020 0 (4)A 
+
+1.490 0 (.)A 
+
+-0.020 0 (1)A 
+
+-1.020 0 (0)A 
+
+-4.020 0 (s)A 
+
+2.980 0 (e)A 
+
+-1.020 0 (c)A 
+
+; : 1114 1169 181 53 rc 0 0 0 sco F0_45
+
+Ji 
+
+1124 1169 M 
+
+-1.020 0 (6)A 
+
+1.490 0 (.)A 
+
+-0.020 0 (5)A 
+
+-1.020 0 (9)A 
+
+-4.020 0 (s)A 
+
+2.980 0 (e)A 
+
+-1.020 0 (c)A 
+
+; : 1111 995 180 53 rc 0 0 0 sco F0_45
+
+Ji 
+
+1121 995 M 
+
+-1.020 0 (6)A 
+
+1.490 0 (.)A 
+
+-0.020 0 (5)A 
+
+-1.020 0 (5)A 
+
+-4.020 0 (s)A 
+
+2.980 0 (e)A 
+
+-1.020 0 (c)A 
+
+; : 1493 821 205 53 rc 0 0 0 sco F0_45
+
+Ji 
+
+1504 821 M 
+
+-1.020 0 (1)A 
+
+-0.020 0 (1)A 
+
+1.490 0 (.)A 
+
+-1.020 0 (32)A 
+
+-4.020 0 (s)A 
+
+2.980 0 (e)A 
+
+-1.020 0 (c)A 
+
+; : 2199 647 205 53 rc 0 0 0 sco F0_45
+
+Ji 
+
+2209 647 M 
+
+-1.020 0 (2)A 
+
+-0.020 0 (0)A 
+
+1.490 0 (.)A 
+
+-1.020 0 (07)A 
+
+-4.020 0 (s)A 
+
+2.980 0 (e)A 
+
+-1.020 0 (c)A 
+
+; : 2550 473 205 53 rc 0 0 0 sco F0_45
+
+Ji 
+
+2561 473 M 
+
+-1.020 0 (2)A 
+
+-0.020 0 (4)A 
+
+1.490 0 (.)A 
+
+-1.020 0 (43)A 
+
+-4.020 0 (s)A 
+
+2.980 0 (e)A 
+
+-1.020 0 (c)A 
+
+; : 217 1892 2841 74 rc 0 0 0 sco %%IncludeFont: Helvetica
+
+(F3) cvn
+
+0.909 
+
+ (Helvetica) cvn /Type1 
+
+T 
+
+(Helvetica) cvn
+
+mF 
+
+(F3_66) cvn
+
+F3
+
+66 
+
+xF 
+
+F3_66
+
+Ji 
+
+335 1892 M 
+
+2.652 0 (I)A 
+
+-1.696 0 (n)A 
+
+1.304 0 (p)A 
+
+-0.978 0 (r)A 
+
+1.304 0 (o1)A 
+
+; : 116 1718 2942 74 rc 0 0 0 sco F3_66
+
+Ji 
+
+179 1718 M 
+
+0.978 0 (B)A 
+
+1.348 0 (C)A 
+
+0.978 0 (SS)A 
+
+1.674 0 (T)A 
+
+0.978 0 (K)A 
+
+2.304 0 (3)A 
+
+1.304 0 (0)A 
+
+; : 116 1544 2942 74 rc 0 0 0 sco F3_66
+
+Ji 
+
+179 1544 M 
+
+0.978 0 (B)A 
+
+1.348 0 (C)A 
+
+0.978 0 (SS)A 
+
+1.674 0 (T)A 
+
+0.978 0 (K)A 
+
+2.304 0 (3)A 
+
+1.304 0 (2)A 
+
+; : 116 1370 2942 74 rc 0 0 0 sco F3_66
+
+Ji 
+
+179 1370 M 
+
+0.978 0 (B)A 
+
+1.348 0 (C)A 
+
+0.978 0 (SS)A 
+
+1.674 0 (T)A 
+
+0.978 0 (K)A 
+
+2.304 0 (3)A 
+
+1.304 0 (1)A 
+
+; : 172 1196 2886 74 rc 0 0 0 sco F3_66
+
+Ji 
+
+290 1196 M 
+
+0.978 0 (P)A 
+
+1.348 0 (D)A 
+
+0.978 0 (S)A 
+
+-0.978 0 (-)A 
+
+1.304 0 (20)A 
+
+; : 196 1026 2862 74 rc 0 0 0 sco F3_66
+
+Ji 
+
+314 1026 M 
+
+0.978 0 (KE)A 
+
+-1.652 0 (N)A 
+
+1.304 0 (18)A 
+
+; : 148 852 2910 74 rc 0 0 0 sco F3_66
+
+Ji 
+
+266 852 M 
+
+1.674 0 (F)A 
+
+0.652 0 (O)A 
+
+1.348 0 (R)A 
+
+0.674 0 (T)A 
+
+2.304 0 (1)A 
+
+1.304 0 (7)A 
+
+; : 280 678 2778 74 rc 0 0 0 sco F3_66
+
+Ji 
+
+398 678 M 
+
+1.674 0 (T)A 
+
+-0.978 0 (r)A 
+
+1.304 0 (o)A 
+
+-0.652 0 (ll)A 
+
+; : 214 505 2844 74 rc 0 0 0 sco F3_66
+
+Ji 
+
+332 505 M 
+
+0.652 0 (O)A 
+
+2.000 0 (c)A 
+
+1.304 0 (e)A 
+
+-1.696 0 (an)A 
+
+; 
+
+784 2059 N M 1971 128 rr : 1.000 1.000 1.000 sco O ; 0 Lc 0 Lj 0 0 0 sco K 
+
+812 2100 N M 52 53 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K : 785 2080 1974 96 rc 0 0 0 sco (F0_83) cvn
+
+F0
+
+83 
+
+xF 
+
+F0_83
+
+Ji 
+
+888 2080 M 
+
+3.861 0 (M)A 
+
+0.926 0 (I)A 
+
+0.287 0 32 0.639 0 (PS )D 
+
+-0.926 0 (R)A 
+
+-1.148 0 (1)A 
+
+-0.148 0 (0)A 
+
+-1.148 0 (000)A 
+
+-0.925 0 (@)A 
+
+-1.148 0 (2)A 
+
+-0.148 0 (0)A 
+
+-1.148 0 (0)A 
+
+3.861 0 (M)A 
+
+-0.926 0 (H)A 
+
+0.500 0 (z)A 
+
+; 
+
+1834 2100 N M 52 53 rr : 0 0 1.000 sco O ; 0 0 0 sco K : 1807 2080 952 96 rc 0 0 0 sco F0_83
+
+Ji 
+
+1910 2080 M 
+
+0.926 0 (I)A 
+
+2.287 0 (n)A 
+
+-0.639 0 (t)A 
+
+-0.148 0 (e)A 
+
+0.926 0 (l )A 
+
+0.639 0 (PP)A 
+
+-0.926 0 (R)A 
+
+-2.574 0 (O)A 
+
+-0.925 0 (@)A 
+
+-1.148 0 (2)A 
+
+-0.148 0 (0)A 
+
+-1.148 0 (0)A 
+
+3.861 0 (M)A 
+
+-0.926 0 (H)A 
+
+0.500 0 (z)A 
+
+; 
+
+1538 1010 N M 320 38 rr : 0.502 0 0 sco O ; 
+
+1538 1048 N M 320 61 rr : 0.502 0 0 sco O ; 
+
+1538 1109 N M 320 37 rr : 0.502 0 0 sco O ; 
+
+1858 1010 N M 361 68 rr : 0.502 0 0 sco O ; : 1516 1010 1425 985 rc 1.000 1.000 1.000 sco %%IncludeFont: Helvetica-BoldOblique
+
+(F6) cvn
+
+0.915 
+
+ (Helvetica-BoldOblique) cvn /Type1 
+
+T 
+
+(Helvetica-BoldOblique) cvn
+
+mF 
+
+(F6_59) cvn
+
+F6
+
+59 
+
+xF 
+
+F6_59
+
+Ji 
+
+1888 1011 M 
+
+0.402 0 (N)A 
+
+0.951 0 (u)A 
+
+1.549 0 (m)A 
+
+0.951 0 (b)A 
+
+0.196 0 (e)A 
+
+0.549 0 32 0.049 0 (r )D 
+
+0.951 0 (o)A 
+
+0.353 0 (f)A 
+
+; 
+
+1858 1078 N M 361 68 rr : 0.502 0 0 sco O ; : 1516 1010 1425 985 rc 1.000 1.000 1.000 sco F6_59
+
+Ji 
+
+1922 1080 M 
+
+0.647 0 (V)A 
+
+0.196 0 (e)A 
+
+0.049 0 (r)A 
+
+1.353 0 (t)A 
+
+0.598 0 (i)A 
+
+0.196 0 (ce)A 
+
+1.196 0 (s)A 
+
+; 
+
+2219 1010 N M 362 68 rr : 0.502 0 0 sco O ; : 1516 1010 1425 985 rc 1.000 1.000 1.000 sco F6_59
+
+Ji 
+
+2250 1011 M 
+
+0.402 0 (N)A 
+
+0.951 0 (u)A 
+
+1.549 0 (m)A 
+
+0.951 0 (b)A 
+
+0.196 0 (e)A 
+
+0.549 0 32 0.049 0 (r )D 
+
+0.951 0 (o)A 
+
+0.353 0 (f)A 
+
+; 
+
+2219 1078 N M 362 68 rr : 0.502 0 0 sco O ; : 1516 1010 1425 985 rc 1.000 1.000 1.000 sco F6_59
+
+Ji 
+
+2311 1080 M 
+
+0.647 0 (E)A 
+
+0.951 0 (dg)A 
+
+0.196 0 (es)A 
+
+; 
+
+2581 1010 N M 360 68 rr : 0.502 0 0 sco O ; : 1516 1010 1425 985 rc 1.000 1.000 1.000 sco F6_59
+
+Ji 
+
+2620 1011 M 
+
+1.098 0 (O)A 
+
+0.951 0 (p)A 
+
+0.196 0 (e)A 
+
+0.049 0 (r)A 
+
+1.196 0 (a)A 
+
+0.353 0 (t)A 
+
+0.598 0 (i)A 
+
+0.951 0 (o)A 
+
+-0.049 0 (n)A 
+
+; 
+
+2581 1078 N M 360 68 rr : 0.502 0 0 sco O ; : 1516 1010 1425 985 rc 1.000 1.000 1.000 sco F6_59
+
+Ji 
+
+2675 1080 M 
+
+0.402 0 (C)A 
+
+0.951 0 (oun)A 
+
+0.353 0 (t)A 
+
+; 
+
+1538 1151 N M 320 13 rr : 1.000 1.000 0.800 sco O ; 
+
+1538 1164 N M 320 61 rr : 1.000 1.000 0.800 sco O ; : 1516 1010 1425 985 rc 0.004 0 0 sco (F0_53) cvn
+
+F0
+
+53 
+
+xF 
+
+F0_53
+
+Ji 
+
+1554 1163 M 
+
+0.766 0 (O)A 
+
+0.532 0 (c)A 
+
+1.532 0 (e)A 
+
+0.532 0 (a)A 
+
+0.617 0 (n)A 
+
+; 
+
+1538 1225 N M 320 14 rr : 1.000 1.000 0.800 sco O ; 
+
+1858 1151 N M 361 13 rr : 1.000 1.000 0.800 sco O ; 
+
+1858 1164 N M 361 61 rr : 1.000 1.000 0.800 sco O ; : 1858 1146 361 79 rc 0.004 0 0 sco (F3_53) cvn
+
+F3
+
+53 
+
+xF 
+
+F3_53
+
+Ji 
+
+2007 1166 M 
+
+0.532 0 (1)A 
+
+1.532 0 (4)A 
+
+0.532 0 (3)A 
+
+0.266 0 (,)A 
+
+0.532 0 (43)A 
+
+1.532 0 (7)A 
+
+; 
+
+1858 1225 N M 361 14 rr : 1.000 1.000 0.800 sco O ; 
+
+2219 1151 N M 362 13 rr : 1.000 1.000 0.800 sco O ; 
+
+2219 1164 N M 362 61 rr : 1.000 1.000 0.800 sco O ; : 2219 1146 362 79 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2369 1166 M 
+
+0.532 0 (4)A 
+
+1.532 0 (0)A 
+
+0.532 0 (9)A 
+
+0.266 0 (,)A 
+
+0.532 0 (59)A 
+
+1.532 0 (3)A 
+
+; 
+
+2219 1225 N M 362 14 rr : 1.000 1.000 0.800 sco O ; 
+
+2581 1151 N M 360 13 rr : 1.000 1.000 0.800 sco O ; 
+
+2581 1164 N M 360 61 rr : 1.000 1.000 0.800 sco O ; : 2581 1146 360 79 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2699 1166 M 
+
+0.532 0 (1)A 
+
+1.266 0 (.)A 
+
+0.532 0 (26e)A 
+
+1.048 0 (+)A 
+
+0.532 0 (0)A 
+
+1.532 0 (8)A 
+
+; 
+
+2581 1225 N M 360 14 rr : 1.000 1.000 0.800 sco O ; 
+
+1538 1146 N M 320 5 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc 
+
+1538 1146 N M 320 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+1858 1146 N M 4 5 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc 
+
+1858 1146 N M 4 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; : 1516 1010 1425 985 rc 
+
+1858 1146 N M 0 5 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+1862 1146 N M 357 5 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc 
+
+1862 1146 N M 357 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+2219 1146 N M 5 5 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc 
+
+2219 1146 N M 5 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; : 1516 1010 1425 985 rc 
+
+2219 1146 N M 0 5 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+2224 1146 N M 357 5 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc 
+
+2224 1146 N M 357 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+2581 1146 N M 5 5 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc 
+
+2581 1146 N M 5 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; : 1516 1010 1425 985 rc 
+
+2581 1146 N M 0 5 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+2586 1146 N M 355 5 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc 
+
+2586 1146 N M 355 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+1538 1239 N M 320 14 rr : 1.000 1.000 0.800 sco O ; 
+
+1538 1253 N M 320 61 rr : 1.000 1.000 0.800 sco O ; : 1516 1010 1425 985 rc 0.004 0 0 sco F0_53
+
+Ji 
+
+1554 1251 M 
+
+0.617 0 (T)A 
+
+0.383 0 (r)A 
+
+1.617 0 (o)A 
+
+0.266 0 (ll)A 
+
+; 
+
+1538 1314 N M 320 14 rr : 1.000 1.000 0.800 sco O ; 
+
+1858 1239 N M 361 14 rr : 1.000 1.000 0.800 sco O ; 
+
+1858 1253 N M 361 61 rr : 1.000 1.000 0.800 sco O ; : 1858 1239 361 75 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2007 1255 M 
+
+0.532 0 (2)A 
+
+1.532 0 (1)A 
+
+0.532 0 (3)A 
+
+0.266 0 (,)A 
+
+0.532 0 (45)A 
+
+1.532 0 (3)A 
+
+; 
+
+1858 1314 N M 361 14 rr : 1.000 1.000 0.800 sco O ; 
+
+2219 1239 N M 362 14 rr : 1.000 1.000 0.800 sco O ; 
+
+2219 1253 N M 362 61 rr : 1.000 1.000 0.800 sco O ; : 2219 1239 362 75 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2323 1255 M 
+
+0.532 0 (5)A 
+
+1.266 0 (,)A 
+
+0.532 0 (885)A 
+
+0.266 0 (,)A 
+
+1.532 0 (8)A 
+
+0.532 0 (29)A 
+
+; 
+
+2219 1314 N M 362 14 rr : 1.000 1.000 0.800 sco O ; 
+
+2581 1239 N M 360 14 rr : 1.000 1.000 0.800 sco O ; 
+
+2581 1253 N M 360 61 rr : 1.000 1.000 0.800 sco O ; : 2581 1239 360 75 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2699 1255 M 
+
+0.532 0 (5)A 
+
+1.266 0 (.)A 
+
+0.532 0 (53e)A 
+
+1.048 0 (+)A 
+
+0.532 0 (1)A 
+
+1.532 0 (0)A 
+
+; 
+
+2581 1314 N M 360 14 rr : 1.000 1.000 0.800 sco O ; 
+
+1538 1328 N M 320 13 rr : 1.000 1.000 0.800 sco O ; 
+
+1538 1341 N M 320 61 rr : 1.000 1.000 0.800 sco O ; : 1516 1010 1425 985 rc 0.004 0 0 sco F0_53
+
+Ji 
+
+1554 1340 M 
+
+0.617 0 (F)A 
+
+1.617 0 (o)A 
+
+0.383 0 (r)A 
+
+0.351 0 (t)A 
+
+0.532 0 (17)A 
+
+; 
+
+1538 1402 N M 320 15 rr : 1.000 1.000 0.800 sco O ; 
+
+1858 1328 N M 361 13 rr : 1.000 1.000 0.800 sco O ; 
+
+1858 1341 N M 361 61 rr : 1.000 1.000 0.800 sco O ; : 1858 1328 361 74 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2037 1344 M 
+
+0.532 0 (8)A 
+
+1.532 0 (6)A 
+
+0.266 0 (,)A 
+
+0.532 0 (650)A 
+
+; 
+
+1858 1402 N M 361 15 rr : 1.000 1.000 0.800 sco O ; 
+
+2219 1328 N M 362 13 rr : 1.000 1.000 0.800 sco O ; 
+
+2219 1341 N M 362 61 rr : 1.000 1.000 0.800 sco O ; : 2219 1328 362 74 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2369 1344 M 
+
+0.532 0 (2)A 
+
+1.532 0 (4)A 
+
+0.532 0 (7)A 
+
+0.266 0 (,)A 
+
+0.532 0 (42)A 
+
+1.532 0 (4)A 
+
+; 
+
+2219 1402 N M 362 15 rr : 1.000 1.000 0.800 sco O ; 
+
+2581 1328 N M 360 13 rr : 1.000 1.000 0.800 sco O ; 
+
+2581 1341 N M 360 61 rr : 1.000 1.000 0.800 sco O ; : 2581 1328 360 74 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2699 1344 M 
+
+0.532 0 (8)A 
+
+1.266 0 (.)A 
+
+0.532 0 (05e)A 
+
+1.048 0 (+)A 
+
+0.532 0 (0)A 
+
+1.532 0 (6)A 
+
+; 
+
+2581 1402 N M 360 15 rr : 1.000 1.000 0.800 sco O ; 
+
+1538 1417 N M 320 13 rr : 1.000 1.000 0.800 sco O ; 
+
+1538 1430 N M 320 61 rr : 1.000 1.000 0.800 sco O ; : 1516 1010 1425 985 rc 0.004 0 0 sco F0_53
+
+Ji 
+
+1554 1429 M 
+
+0.734 0 (K)A 
+
+0.532 0 (e)A 
+
+1.617 0 (n)A 
+
+0.532 0 (1)A 
+
+1.532 0 (8)A 
+
+; 
+
+1538 1491 N M 320 14 rr : 1.000 1.000 0.800 sco O ; 
+
+1858 1417 N M 361 13 rr : 1.000 1.000 0.800 sco O ; 
+
+1858 1430 N M 361 61 rr : 1.000 1.000 0.800 sco O ; : 1858 1417 361 74 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2007 1432 M 
+
+0.532 0 (1)A 
+
+1.532 0 (0)A 
+
+0.532 0 (5)A 
+
+0.266 0 (,)A 
+
+0.532 0 (12)A 
+
+1.532 0 (7)A 
+
+; 
+
+1858 1491 N M 361 14 rr : 1.000 1.000 0.800 sco O ; 
+
+2219 1417 N M 362 13 rr : 1.000 1.000 0.800 sco O ; 
+
+2219 1430 N M 362 61 rr : 1.000 1.000 0.800 sco O ; : 2219 1417 362 74 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2369 1432 M 
+
+0.532 0 (2)A 
+
+1.532 0 (5)A 
+
+0.532 0 (2)A 
+
+0.266 0 (,)A 
+
+0.532 0 (07)A 
+
+1.532 0 (2)A 
+
+; 
+
+2219 1491 N M 362 14 rr : 1.000 1.000 0.800 sco O ; 
+
+2581 1417 N M 360 13 rr : 1.000 1.000 0.800 sco O ; 
+
+2581 1430 N M 360 61 rr : 1.000 1.000 0.800 sco O ; : 2581 1417 360 74 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2699 1432 M 
+
+0.532 0 (2)A 
+
+1.266 0 (.)A 
+
+0.532 0 (85e)A 
+
+1.048 0 (+)A 
+
+0.532 0 (0)A 
+
+1.532 0 (8)A 
+
+; 
+
+2581 1491 N M 360 14 rr : 1.000 1.000 0.800 sco O ; 
+
+1538 1505 N M 320 14 rr : 1.000 1.000 0.800 sco O ; 
+
+1538 1519 N M 320 61 rr : 1.000 1.000 0.800 sco O ; : 1516 1010 1425 985 rc 0.004 0 0 sco F0_53
+
+Ji 
+
+1554 1517 M 
+
+0.649 0 (P)A 
+
+0.734 0 (D)A 
+
+0.649 0 (S)A 
+
+1.351 0 (-)A 
+
+0.532 0 (20)A 
+
+; 
+
+1538 1580 N M 320 14 rr : 1.000 1.000 0.800 sco O ; 
+
+1858 1505 N M 361 14 rr : 1.000 1.000 0.800 sco O ; 
+
+1858 1519 N M 361 61 rr : 1.000 1.000 0.800 sco O ; : 1858 1505 361 75 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2037 1521 M 
+
+0.532 0 (3)A 
+
+1.532 0 (3)A 
+
+0.266 0 (,)A 
+
+0.532 0 (798)A 
+
+; 
+
+1858 1580 N M 361 14 rr : 1.000 1.000 0.800 sco O ; 
+
+2219 1505 N M 362 14 rr : 1.000 1.000 0.800 sco O ; 
+
+2219 1519 N M 362 61 rr : 1.000 1.000 0.800 sco O ; : 2219 1505 362 75 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2369 1521 M 
+
+0.532 0 (1)A 
+
+1.532 0 (4)A 
+
+0.532 0 (3)A 
+
+0.266 0 (,)A 
+
+0.532 0 (16)A 
+
+1.532 0 (1)A 
+
+; 
+
+2219 1580 N M 362 14 rr : 1.000 1.000 0.800 sco O ; 
+
+2581 1505 N M 360 14 rr : 1.000 1.000 0.800 sco O ; 
+
+2581 1519 N M 360 61 rr : 1.000 1.000 0.800 sco O ; : 2581 1505 360 75 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2699 1521 M 
+
+0.532 0 (3)A 
+
+1.266 0 (.)A 
+
+0.532 0 (82e)A 
+
+1.048 0 (+)A 
+
+0.532 0 (0)A 
+
+1.532 0 (9)A 
+
+; 
+
+2581 1580 N M 360 14 rr : 1.000 1.000 0.800 sco O ; 
+
+1538 1594 N M 320 14 rr : 1.000 1.000 0.800 sco O ; 
+
+1538 1608 N M 320 61 rr : 1.000 1.000 0.800 sco O ; : 1538 1594 320 75 rc 0.004 0 0 sco F0_53
+
+Ji 
+
+1554 1606 M 
+
+0.734 0 (BC)A 
+
+0.649 0 (S)A 
+
+1.649 0 (S)A 
+
+0.617 0 (T)A 
+
+0.734 0 (K)A 
+
+0.532 0 (3)A 
+
+1.532 0 (1)A 
+
+; 
+
+1538 1669 N M 320 14 rr : 1.000 1.000 0.800 sco O ; 
+
+1858 1594 N M 361 14 rr : 1.000 1.000 0.800 sco O ; 
+
+1858 1608 N M 361 61 rr : 1.000 1.000 0.800 sco O ; : 1858 1594 361 75 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2037 1610 M 
+
+0.532 0 (3)A 
+
+1.532 0 (5)A 
+
+0.266 0 (,)A 
+
+0.532 0 (588)A 
+
+; 
+
+1858 1669 N M 361 14 rr : 1.000 1.000 0.800 sco O ; 
+
+2219 1594 N M 362 14 rr : 1.000 1.000 0.800 sco O ; 
+
+2219 1608 N M 362 61 rr : 1.000 1.000 0.800 sco O ; : 2219 1594 362 75 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2369 1610 M 
+
+0.532 0 (5)A 
+
+1.532 0 (7)A 
+
+0.532 0 (2)A 
+
+0.266 0 (,)A 
+
+0.532 0 (91)A 
+
+1.532 0 (4)A 
+
+; 
+
+2219 1669 N M 362 14 rr : 1.000 1.000 0.800 sco O ; 
+
+2581 1594 N M 360 14 rr : 1.000 1.000 0.800 sco O ; 
+
+2581 1608 N M 360 61 rr : 1.000 1.000 0.800 sco O ; : 2581 1594 360 75 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2699 1610 M 
+
+0.532 0 (1)A 
+
+1.266 0 (.)A 
+
+0.532 0 (16e)A 
+
+1.048 0 (+)A 
+
+0.532 0 (0)A 
+
+1.532 0 (9)A 
+
+; 
+
+2581 1669 N M 360 14 rr : 1.000 1.000 0.800 sco O ; 
+
+1538 1683 N M 320 13 rr : 1.000 1.000 0.800 sco O ; 
+
+1538 1696 N M 320 61 rr : 1.000 1.000 0.800 sco O ; : 1538 1683 320 74 rc 0.004 0 0 sco F0_53
+
+Ji 
+
+1554 1695 M 
+
+0.734 0 (BC)A 
+
+0.649 0 (S)A 
+
+1.649 0 (S)A 
+
+0.617 0 (T)A 
+
+0.734 0 (K)A 
+
+0.532 0 (3)A 
+
+1.532 0 (2)A 
+
+; 
+
+1538 1757 N M 320 14 rr : 1.000 1.000 0.800 sco O ; 
+
+1858 1683 N M 361 13 rr : 1.000 1.000 0.800 sco O ; 
+
+1858 1696 N M 361 61 rr : 1.000 1.000 0.800 sco O ; : 1858 1683 361 74 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2037 1698 M 
+
+0.532 0 (4)A 
+
+1.532 0 (4)A 
+
+0.266 0 (,)A 
+
+0.532 0 (609)A 
+
+; 
+
+1858 1757 N M 361 14 rr : 1.000 1.000 0.800 sco O ; 
+
+2219 1683 N M 362 13 rr : 1.000 1.000 0.800 sco O ; 
+
+2219 1696 N M 362 61 rr : 1.000 1.000 0.800 sco O ; : 2219 1683 362 74 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2369 1698 M 
+
+0.532 0 (9)A 
+
+1.532 0 (8)A 
+
+0.532 0 (5)A 
+
+0.266 0 (,)A 
+
+0.532 0 (04)A 
+
+1.532 0 (6)A 
+
+; 
+
+2219 1757 N M 362 14 rr : 1.000 1.000 0.800 sco O ; 
+
+2581 1683 N M 360 13 rr : 1.000 1.000 0.800 sco O ; 
+
+2581 1696 N M 360 61 rr : 1.000 1.000 0.800 sco O ; : 2581 1683 360 74 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2699 1698 M 
+
+0.532 0 (1)A 
+
+1.266 0 (.)A 
+
+0.532 0 (32e)A 
+
+1.048 0 (+)A 
+
+0.532 0 (0)A 
+
+1.532 0 (9)A 
+
+; 
+
+2581 1757 N M 360 14 rr : 1.000 1.000 0.800 sco O ; 
+
+1538 1771 N M 320 14 rr : 1.000 1.000 0.800 sco O ; 
+
+1538 1785 N M 320 61 rr : 1.000 1.000 0.800 sco O ; : 1538 1771 320 75 rc 0.004 0 0 sco F0_53
+
+Ji 
+
+1554 1784 M 
+
+0.734 0 (BC)A 
+
+0.649 0 (S)A 
+
+1.649 0 (S)A 
+
+0.617 0 (T)A 
+
+0.734 0 (K)A 
+
+0.532 0 (3)A 
+
+1.532 0 (0)A 
+
+; 
+
+1538 1846 N M 320 14 rr : 1.000 1.000 0.800 sco O ; 
+
+1858 1771 N M 361 14 rr : 1.000 1.000 0.800 sco O ; 
+
+1858 1785 N M 361 61 rr : 1.000 1.000 0.800 sco O ; : 1858 1771 361 75 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2037 1787 M 
+
+0.532 0 (2)A 
+
+1.532 0 (8)A 
+
+0.266 0 (,)A 
+
+0.532 0 (294)A 
+
+; 
+
+1858 1846 N M 361 14 rr : 1.000 1.000 0.800 sco O ; 
+
+2219 1771 N M 362 14 rr : 1.000 1.000 0.800 sco O ; 
+
+2219 1785 N M 362 61 rr : 1.000 1.000 0.800 sco O ; : 2219 1771 362 75 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2323 1787 M 
+
+0.532 0 (1)A 
+
+1.266 0 (,)A 
+
+0.532 0 (007)A 
+
+0.266 0 (,)A 
+
+1.532 0 (2)A 
+
+0.532 0 (84)A 
+
+; 
+
+2219 1846 N M 362 14 rr : 1.000 1.000 0.800 sco O ; 
+
+2581 1771 N M 360 14 rr : 1.000 1.000 0.800 sco O ; 
+
+2581 1785 N M 360 61 rr : 1.000 1.000 0.800 sco O ; : 2581 1771 360 75 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2699 1787 M 
+
+0.532 0 (1)A 
+
+1.266 0 (.)A 
+
+0.532 0 (17e)A 
+
+1.048 0 (+)A 
+
+0.532 0 (0)A 
+
+1.532 0 (9)A 
+
+; 
+
+2581 1846 N M 360 14 rr : 1.000 1.000 0.800 sco O ; 
+
+1538 1860 N M 320 16 rr : 1.000 1.000 0.800 sco O ; 
+
+1538 1876 N M 320 61 rr : 1.000 1.000 0.800 sco O ; : 1516 1010 1425 985 rc 0.004 0 0 sco F0_53
+
+Ji 
+
+1554 1874 M 
+
+0.266 0 (I)A 
+
+0.617 0 (n)A 
+
+1.617 0 (p)A 
+
+0.383 0 (r)A 
+
+0.617 0 (o)A 
+
+0.532 0 (1)A 
+
+; 
+
+1538 1937 N M 320 17 rr : 1.000 1.000 0.800 sco O ; 
+
+1858 1860 N M 361 16 rr : 1.000 1.000 0.800 sco O ; 
+
+1858 1876 N M 361 61 rr : 1.000 1.000 0.800 sco O ; : 1858 1860 361 77 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2037 1878 M 
+
+0.532 0 (4)A 
+
+1.532 0 (6)A 
+
+0.266 0 (,)A 
+
+0.532 0 (949)A 
+
+; 
+
+1858 1937 N M 361 17 rr : 1.000 1.000 0.800 sco O ; 
+
+2219 1860 N M 362 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2219 1876 N M 362 61 rr : 1.000 1.000 0.800 sco O ; : 2219 1860 362 77 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2323 1878 M 
+
+0.532 0 (1)A 
+
+1.266 0 (,)A 
+
+0.532 0 (117)A 
+
+0.266 0 (,)A 
+
+1.532 0 (8)A 
+
+0.532 0 (09)A 
+
+; 
+
+2219 1937 N M 362 17 rr : 1.000 1.000 0.800 sco O ; 
+
+2581 1860 N M 360 16 rr : 1.000 1.000 0.800 sco O ; 
+
+2581 1876 N M 360 61 rr : 1.000 1.000 0.800 sco O ; : 2581 1860 360 77 rc 0.004 0 0 sco F3_53
+
+Ji 
+
+2699 1878 M 
+
+0.532 0 (1)A 
+
+1.266 0 (.)A 
+
+0.532 0 (24e)A 
+
+1.048 0 (+)A 
+
+0.532 0 (0)A 
+
+1.532 0 (9)A 
+
+; 
+
+2581 1937 N M 360 17 rr : 1.000 1.000 0.800 sco O ; 
+
+1538 1954 N M 320 4 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc 
+
+1538 1954 N M 320 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+1858 1954 N M 4 4 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc 
+
+1858 1954 N M 4 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; : 1516 1010 1425 985 rc 
+
+1858 1954 N M 0 4 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+1862 1954 N M 357 4 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc 
+
+1862 1954 N M 357 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+2219 1954 N M 5 4 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc 
+
+2219 1954 N M 5 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; : 1516 1010 1425 985 rc 
+
+2219 1954 N M 0 4 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+2224 1954 N M 357 4 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc 
+
+2224 1954 N M 357 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+2581 1954 N M 5 4 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc 
+
+2581 1954 N M 5 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; : 1516 1010 1425 985 rc 
+
+2581 1954 N M 0 4 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+2586 1954 N M 355 4 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc 
+
+2586 1954 N M 355 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; 
+
+LH 
+
+pagesave restore
+
+
+
+
+
+
+
+/Pscript_Win_Driver /ProcSet findresource dup /terminate get exec
+
+Pscript_Win_Compat dup /terminate get exec
+
+
+cleartomark
+countdictstack exch sub { end } repeat
+restore grestore
+%
+% End Imported PIC File: slide2.eps
+%
+$F2psEnd
+rs
+%%EndDocument
+ @endspecial 0 3899 a Fy(Figure)19 b(2)p FL(:)28 b Fx(The)19
+b(amount)g(of)h(time)g(required)f(b)o(y)i(M)l Fv(E)-17
+b Fx(T)g Fv(I)p Fx(S)23 b(to)d(par)s(tition)f(v)n(ar)q(ious)h(g)o(r)o
+(aphs)f(in)h(256)g(par)s(ts)f(and)h(the)f(amount)g(of)h(time)g
+(required)e(b)o(y)k(M)l Fv(E)-17 b Fx(T)g Fv(I)p Fx(S)0
+3999 y(to)19 b(compute)f(\002ll-reducing)g(order)q(ings)f(f)n(or)i(v)n
+(ar)q(ious)f(sparse)h(matr)q(ices)o(.)100 4183 y FL(The)i(rest)h(of)f
+(this)i(manual)d(is)j(or)o(ganized)c(as)j(follo)n(ws:)28
+b(Section)21 b(4)h(describes)f(the)h(user)f(interf)o(ace)g(to)h(the)f
+(stand-alone)f(programs)0 4292 y(pro)o(vided)i(by)k Fz(M)l
+FG(E)-17 b Fz(T)g FG(I)p Fz(S)r FL(.)26 b(Section)e(5)g(describes)g
+(the)g(stand-alone)f(library)g(that)i(implements)e(the)h(v)n(arious)f
+(algorithms)g(implemented)0 4402 y(in)f Fz(M)l FG(E)-17
+b Fz(T)g FG(I)p Fz(S)r FL(.)23 b(Finally)-5 b(,)19 b(Section)h(6)g
+(describes)g(the)g(system)g(requirements)f(for)g(the)j
+Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)25 b FL(package.)1929
+5649 y(5)p eop
+%%Page: 6 6
+6 5 bop 0 85 a FD(3)116 b(What)31 b(is)h(Ne)n(w)h(in)g(This)f(V)-6
+b(er)n(sion)0 261 y FL(The)19 b(latest)i(v)o(ersion)d(of)j
+Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)24 b FL(contains)19
+b(a)h(number)d(of)i(changes)g(o)o(v)o(er)f(the)i(pre)n(vious)e(major)g
+(release)i(\(v)o(ersion)e(3.0\).)23 b(Most)d(of)f(these)0
+370 y(changes)h(are)g(concentrated)e(on)i(the)h(graph)e(and)h(mesh)g
+(partitioning)f(routines)h(and)g(the)o(y)f(mar)o(ginally)g(af)n(fect)h
+(the)g(sparse)h(matrix)f(re-)0 480 y(ordering)c(routines.)23
+b(T)-7 b(able)18 b(1)h(describes)e(which)h(programs)e(and)i(routines)f
+(of)j Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)21 b
+FL(ha)n(v)o(e)d(been)f(changed)g(and)g(the)i(ne)n(w)f(routines)0
+590 y(in)k Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)p
+FL(.)29 b(In)20 b(the)g(rest)g(of)g(this)h(section)f(we)g(brie\003y)g
+(describe)f(some)h(of)g(the)h(major)e(changes.)0 799
+y FB(Multi-Constraint)24 b(P)n(ar)r(titioning)100 b Fz(M)l
+FG(E)-17 b Fz(T)g FG(I)p Fz(S)26 b FL(no)n(w)c(includes)f(partitioning)
+f(routines)h(that)h(can)g(be)g(used)g(to)g(partition)f(a)i(graph)d(in)0
+908 y(the)e(presence)e(of)h(multiple)g(balancing)f(constraints.)24
+b(The)17 b(idea)g(is)i(that)e(each)g(v)o(erte)o(x)g(has)g(a)h(v)o
+(ector)f(of)g(weights)g(of)h(size)g Ft(m)23 b FL(associated)0
+1018 y(with)g(it,)i(and)d(the)h(objecti)n(v)o(e)f(of)h(the)g
+(partitioning)e(algorithm)h(is)i(to)f(minimize)g(the)g(edgecut)f
+(subject)h(to)g(the)g(constraints)g(that)g(each)0 1128
+y(one)i(of)g(the)h Ft(m)31 b FL(weights)25 b(is)i(equally)e(distrib)n
+(uted)f(among)g(the)i(domains.)40 b(F)o(or)25 b(e)o(xample,)h(if)f(the)
+h(\002rst)g(weight)f(corresponds)f(to)i(the)0 1237 y(amount)c(of)i
+(computation)d(and)i(the)g(second)g(weight)g(corresponds)f(to)h(the)h
+(amount)e(of)i(storage)e(required)g(for)h(each)g(element,)h(then)0
+1347 y(the)19 b(partitioning)f(computed)f(by)i(the)g(ne)n(w)g
+(algorithms)f(will)i(balance)e(both)h(the)g(computation)e(performed)g
+(in)i(each)g(domain)f(as)i(well)0 1456 y(as)f(the)e(amount)g(of)g
+(memory)f(that)i(it)h(requires.)k(Also,)18 b(multi-phase)f
+(\(multi-physics\))e(computations)h(can)h(use)h(the)g(ne)n(w)g
+(partitioning)0 1566 y(algorithm)28 b(to)i(simultaneously)e(balance)h
+(the)h(computations)e(performed)f(in)j(each)f(phase.)53
+b(The)30 b(multi-constraint)e(partitioning)0 1675 y(algorithms)19
+b(and)h(their)f(applications)g(are)i(further)d(described)h(in)i([6)o
+(].)100 1785 y(The)46 b(multi-constraint)f(partitioning)g(algorithm)h
+(is)i(implemented)d(by)h(the)h Fz(METIS)p 2781 1785 25
+4 v 31 w(mCP)m(ar)s(tGr)o(aphRecursiv)n(e)g FL(and)0
+1895 y Fz(METIS)p 258 1895 V 31 w(mCP)m(ar)s(tGr)o(aphKw)o(a)n(y)25
+b FL(routines)g(that)h(are)g(based)g(on)f(the)h(multile)n(v)o(el)f
+(recursi)n(v)o(e)f(bisection)h(and)g(the)h(multile)n(v)o(el)f
+Ft(k)5 b FL(-w)o(ay)0 2004 y(partitioning)21 b(paradigms,)i(respecti)n
+(v)o(ely)-5 b(.)32 b(Also,)24 b(the)g Fz(pmetis)g FL(and)f(the)g
+Fz(kmetis)h FL(programs)d(ha)n(v)o(e)i(been)g(o)o(v)o(erloaded)d(to)j
+(in)m(v)n(ok)o(e)g(the)0 2114 y(multi-constraint)h(partitioner)g(when)i
+(the)g(input)f(graph)g(contains)g(multiple)g(v)o(erte)o(x)g(weights)h
+(\(Section)f(4.5.1)g(describes)g(ho)n(w)h(the)0 2223
+y(format)19 b(of)h(the)g(input)g(graph)e(\002le)j(has)g(been)e(e)o
+(xtended)f(to)j(allo)n(w)f(you)f(to)i(specify)e(multiple)h(v)o(erte)o
+(x)e(weights\).)0 2433 y FB(Minimizing)25 b(the)g(T)-7
+b(otal)25 b(Comm)n(unication)f(V)-7 b(olume)99 b FL(The)22
+b(objecti)n(v)o(e)f(of)i(the)f(traditional)f(graph)g(partitioning)g
+(problem)g(is)0 2542 y(to)f(compute)e(a)i(balanced)e
+Ft(k)5 b FL(-w)o(ay)19 b(partitioning)f(such)h(that)h(the)g(number)d
+(of)j(edges)f(\(or)g(in)h(the)f(case)h(of)g(weighted)e(graphs)h(the)g
+(sum)h(of)0 2652 y(their)f(weights\))g(that)h(straddle)f(dif)n(ferent)f
+(partitions)h(is)i(minimized.)i(When)d(partitioning)d(is)k(used)e(to)h
+(distrib)n(ute)f(a)h(graph)e(or)i(a)g(mesh)0 2761 y(among)f(the)i
+(processors)f(of)h(a)g(parallel)f(computer)m(,)f(the)i(objecti)n(v)o(e)
+e(of)i(minimizing)e(the)i(edgecut)f(is)h(only)f(an)h(approximation)d
+(of)j(the)0 2871 y(true)j(communication)e(cost)i(resulting)g(from)f
+(the)i(partitioning.)36 b(Despite)24 b(that,)i(for)d(a)i(wide)g(range)e
+(of)h(problems,)g(by)g(minimizing)0 2981 y(the)c(edgecut,)f(the)h
+(partitioning)e(algorithms)h(also)i(minimize)e(the)h(communication)e
+(cost)i(reasonably)f(well.)100 3090 y(Ho)n(we)n(v)o(er)m(,)29
+b(there)f(are)h(cases)h(in)f(which)f(a)i(partitioning)d(algorithm)g
+(can)i(signi\002cantly)f(reduce)g(the)h(communication)d(cost)j(by)0
+3200 y(directly)24 b(minimizing)f(this)j(objecti)n(v)o(e)d(\(as)i
+(opposed)e(to)i(the)g(edgecut\).)39 b Fz(M)l FG(E)-17
+b Fz(T)g FG(I)p Fz(S)29 b FL(no)n(w)c(pro)o(vides)e(the)i
+Fz(METIS)p 3238 3200 V 30 w(P)m(ar)s(tGr)o(aphVKw)o(a)n(y)0
+3309 y FL(and)32 b Fz(METIS)p 411 3309 V 30 w(WP)m(ar)s(tGr)o(aphVKw)o
+(a)n(y)h FL(routines)e(that)h(directly)g(minimize)f(the)h
+(communication)d(cost)k(as)g(de\002ned)e(by)g(the)h(total)0
+3419 y(communication)16 b(v)n(olume)i(resulted)g(by)h(the)g
+(partitioning)e(\(see)i(Section)g(5.3)f(for)g(a)i(precise)e
+(de\002nition)g(of)h(this)g(objecti)n(v)o(e)f(function\).)0
+3529 y(Note)24 b(that)g(for)f(these)h(routines)f(to)g(pro)o(vide)f
+(meaningful)g(partitionings,)g(the)i(connecti)n(vity)e(of)h(the)h
+(graph)f(should)f(re\003ect)i(the)g(true)0 3638 y(information)18
+b(e)o(xchange)g(requirements)g(of)i(the)g(underlying)e(computation.)0
+3847 y FB(Minimizing)28 b(the)g(Maxim)n(um)h(Connectivity)f(of)g(the)h
+(Subdomains)99 b FL(The)25 b(communication)d(cost)k(resulting)e(from)h
+(a)h Ft(k)5 b FL(-)0 3957 y(w)o(ay)23 b(partitioning)e(in)j(general)e
+(depends)g(on)g(the)i(follo)n(wing)d(f)o(actors:)31 b(\(i\))23
+b(the)g(total)h(communication)c(v)n(olume,)j(\(ii\))g(the)g(maximum)0
+4067 y(amount)e(of)i(data)f(that)h(an)o(y)f(particular)f(processor)g
+(needs)h(to)h(send)g(and)f(recei)n(v)o(e;)h(and)f(\(iii\))g(the)h
+(number)e(of)h(messages)h(a)g(processor)0 4176 y(needs)f(to)h(send)g
+(and)f(recei)n(v)o(e.)31 b(The)23 b(partitioning)d(routines)i(in)h
+(earlier)f(v)o(ersions)g(of)i Fz(M)l FG(E)-17 b Fz(T)g
+FG(I)p Fz(S)27 b FL(concentrated)21 b(only)h(on)g(the)h(\002rst)g(f)o
+(actor)0 4286 y(\(by)30 b(minimizing)f(the)h(edgecut\).)54
+b(In)30 b(this)h(release,)k Fz(M)l FG(E)-17 b Fz(T)g
+FG(I)p Fz(S)35 b FL(also)c(pro)o(vides)d(support)i(for)f(minimizing)g
+(the)i(third)f(f)o(actor)f(\(which)0 4395 y(essentially)21
+b(reduces)f(the)h(number)e(of)h(startups\))g(and)h(indirectly)e(\(up)h
+(to)h(a)g(point\))f(reduces)g(the)h(second)f(f)o(actor)-5
+b(.)26 b(Experiments)19 b(ha)n(v)o(e)0 4505 y(sho)n(wn)26
+b(that)h(for)f(most)h(graphs)e(corresponding)e(to)k(\002nite)g(element)
+f(meshes,)i(the)f(ne)n(w)g(release)f(of)j Fz(M)l FG(E)-17
+b Fz(T)g FG(I)p Fz(S)31 b FL(is)d(able)e(to)h(reduce)f(the)0
+4614 y(maximum)i(\(and)g(total\))h(number)f(of)h(adjacent)f(subdomains)
+g(considerably\227especially)e(when)j(the)g(graph)f(is)i(partitioned)e
+(in)h(a)0 4724 y(relati)n(v)o(ely)18 b(lar)o(ge)g(number)f(of)i
+(partitions)f(\()p Fs(e)o(.g)o FL(.,)h(greater)f(than)h(30\).)24
+b(F)o(or)19 b(most)g(3D)g(\002nite)g(elements)g(graphs,)f(the)h
+(maximum)e(number)0 4834 y(of)j(subdomains)e(for)i(a)h(50-w)o(ay)d
+(partition)i(has)g(been)f(reduced)g(from)g(around)f(25)i(to)h(around)d
+(16.)100 4943 y(This)66 b(enhancement)d(is)j(pro)o(vided)e(as)i(a)g
+(re\002nement)e(option)h(for)g(both)g(the)h Fz(METIS)p
+3041 4943 V 30 w(P)m(ar)s(tGr)o(aphKw)o(a)n(y)g FL(and)0
+5053 y Fz(METIS)p 258 5053 V 31 w(P)m(ar)s(tGr)o(aphVKw)o(a)n(y)20
+b FL(routines,)f(and)h(is)h(the)f(def)o(ault)g(option)f(of)g
+Fz(kmetis)i FL(and)f Fz(METIS)p 2822 5053 V 30 w(P)m(ar)s(tGr)o(aphKw)o
+(a)n(y)p FL(.)0 5262 y FB(Reducing)28 b(the)h(Number)g(of)f
+(Non-Contiguous)e(Subdomains)99 b FL(A)26 b Ft(k)5 b
+FL(-w)o(ay)25 b(partitioning)f(of)h(a)h(contiguous)e(graph)g(can)0
+5372 y(often)h(lead)g(to)h(some)f(subdomains)f(being)g(assigned)h
+(non-contiguous)d(portions)i(of)i(the)f(graph.)40 b(F)o(or)25
+b(man)o(y)f(problems,)h(the)h(non-)1929 5649 y(6)p eop
+%%Page: 7 7
+7 6 bop 120 100 3661 17 v 120 199 a Fr(Chang)q(es)28
+b(in)i(M)-6 b Fq(E)-21 b Fr(T)g Fq(I)o Fr(S)r(')-6 b(s)33
+b(stand-alone)c(pr)n(ograms)p 120 257 V 120 357 a Fz(pmetis)1016
+b FL(It)24 b(has)f(been)g(o)o(v)o(er)n(-loaded)d(to)j(in)m(v)n(ok)o(e)f
+(the)i(multi-constraint)d(partitioning)g(algo-)1380 457
+y(rithm)f(when)f(the)h(graph)f(contains)h(multiple)f(v)o(erte)o(x)g
+(weights.)120 643 y Fz(kmetis)1020 b FL(It)24 b(has)f(been)g(o)o(v)o
+(er)n(-loaded)d(to)j(in)m(v)n(ok)o(e)f(the)i(multi-constraint)d
+(partitioning)g(algo-)1380 742 y(rithm)f(when)f(the)h(graph)f(contains)
+h(multiple)f(v)o(erte)o(x)g(weights.)1380 842 y(The)k(partitioning)e
+(algorithm)h(has)h(been)f(modi\002ed)g(to)i(also)f(minimize)f(the)h
+(con-)1380 941 y(necti)n(vity)c(of)h(the)g(subdomains.)1380
+1041 y(A)f(pre-)e(and)g(post-re\002nement)f(step)i(is)h(applied)e(that)
+i(tries)f(to)g(reduce)f(the)h(number)1380 1141 y(of)i(non-contiguous)c
+(subdomains.)120 1327 y Fz(par)s(tnmesh)120 1426 y(par)s(tdmesh)1380
+1327 y FL(The)23 b(partitioning)e(algorithm)h(has)h(been)f(modi\002ed)g
+(to)i(also)f(minimize)f(the)h(con-)1380 1426 y(necti)n(vity)c(of)h(the)
+g(subdomains.)p 120 1469 V 120 1768 V 120 1868 a Fr(Chang)q(es)28
+b(in)i(M)-6 b Fq(E)-21 b Fr(T)g Fq(I)o Fr(S)r(lib')-6
+b(s)32 b(r)n(outines)p 120 1926 V 120 2025 a Fz(METIS)p
+378 2025 25 4 v 31 w(P)m(ar)s(tGr)o(aphKw)o(a)n(y)120
+2125 y(METIS)p 378 2125 V 31 w(WP)m(ar)s(tGr)o(aphKw)o(a)n(y)1380
+2025 y FL(A)19 b(ne)n(w)f(re\002nement)f(algorithm)f(has)j(been)e
+(added)h(that)g(also)g(minimizes)g(the)g(con-)1380 2125
+y(necti)n(vity)j(of)i(the)f(subdomains.)30 b(This)22
+b(ne)n(w)h(algorithm)d(has)j(been)f(made)g(the)g(de-)1380
+2225 y(f)o(ault)e(option.)1380 2324 y(A)f(pre-)e(and)g
+(post-re\002nement)f(step)i(is)h(applied)e(that)i(tries)f(to)g(reduce)f
+(the)h(number)1380 2424 y(of)i(non-contiguous)c(subdomains.)120
+2611 y Fz(METIS)p 378 2611 V 31 w(P)m(ar)s(tGr)o(aphVKw)o(a)n(y)120
+2710 y(METIS)p 378 2710 V 31 w(WP)m(ar)s(tGr)o(aphVKw)o(a)n(y)1380
+2611 y FL(This)28 b(is)h(a)f(ne)n(w)g(set)g(of)g(routines)f(that)h
+(compute)e(a)j Ft(k)5 b FL(-w)o(ay)27 b(partitioning)f(whose)1380
+2710 y(objecti)n(v)o(e)19 b(is)i(to)f(minimize)g(the)g(total)g
+(communication)e(v)n(olume.)120 2898 y Fz(METIS)p 378
+2898 V 31 w(mCP)m(ar)s(tGr)o(aphRecursiv)n(e)120 2997
+y(METIS)p 378 2997 V 31 w(mCP)m(ar)s(tGr)o(aphKw)o(a)n(y)1380
+2898 y FL(This)h(is)h(a)f(ne)n(w)g(set)h(of)e(routines)g(that)h
+(compute)f(a)h Ft(k)5 b FL(-w)o(ay)19 b(partitioning)e(subject)h(to)
+1380 2997 y(multiple)i(balancing)e(constraints.)p 120
+3040 3661 17 v 1105 3276 a Fy(T)-5 b(ab)o(le)18 b(1)p
+FL(:)26 b Fx(Summar)r(y)18 b(of)h(the)f(changes)h(in)h(M)l
+Fv(E)-17 b Fx(T)g Fv(I)p Fx(S)22 b(and)f(M)l Fv(E)-17
+b Fx(T)g Fv(I)p Fx(S)r(lib.)0 3459 y FL(contiguity)23
+b(is)j(a)f(result)g(of)g(the)g(underlying)d(geometry)h(and)i(often)f
+(leads)h(to)g(better)g(quality)f(partitions.)38 b(Ne)n(v)o(ertheless,)
+25 b(there)g(are)0 3569 y(cases)32 b(in)g(which)e(the)i(partitioning)d
+(algorithm)h(is)i(fooled)e(and)h(breaks)f(certain)h(domains.)59
+b Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)36 b FL(no)n(w)31
+b(pro)o(vides)e(support)h(for)0 3678 y(eliminating)19
+b(such)h(spurious)f(non-contiguous)d(subdomains.)100
+3788 y(This)j(support)f(is)i(pro)o(vided)c(as)k(a)f(def)o(ault)g
+(option)f(for)g(both)g(the)h Fz(METIS)p 2213 3788 25
+4 v 31 w(P)m(ar)s(tGr)o(aphKw)o(a)n(y)g FL(and)g Fz(METIS)p
+3238 3788 V 30 w(P)m(ar)s(tGr)o(aphVKw)o(a)n(y)0 3898
+y FL(routines,)g(and)h(the)g Fz(kmetis)g FL(program.)1929
+5649 y(7)p eop
+%%Page: 8 8
+8 7 bop 0 85 a FD(4)119 b(M)-6 b FA(E)-23 b FD(T)g FA(I)p
+FD(S)s(')-7 b(s)31 b(Stand-Alone)g(Pr)n(ograms)2 261
+y Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)32 b FL(pro)o(vides)27
+b(a)h(v)n(ariety)f(of)h(programs)e(that)i(can)g(be)g(used)g(to)g
+(partition)f(graphs,)h(partition)f(meshes,)j(compute)d(\002ll-reducing)
+0 370 y(orderings)21 b(of)i(sparse)h(matrices,)f(as)h(well)g(as)g
+(programs)d(to)j(con)m(v)o(ert)d(meshes)i(into)g(graphs)f(appropriate)f
+(for)j Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r FL(')-5
+b(s)26 b(graph)c(parti-)0 480 y(tioning)d(programs.)100
+590 y(The)j(rest)h(of)f(this)h(section)f(pro)o(vides)e(detailed)i
+(descriptions)f(about)h(the)g(functionality)f(of)h(these)g(programs,)f
+(ho)n(w)h(to)h(use)f(them,)0 699 y(the)e(format)f(of)h(the)g(input)g
+(\002les)h(required)d(by)i(them,)g(and)f(the)i(format)e(of)h(the)g
+(produced)d(output)i(\002les.)0 927 y Fr(4.1)100 b(Graph)27
+b(P)m(ar)r(titioning)g(Pr)n(ograms)2 1086 y Fz(M)l FG(E)-17
+b Fz(T)g FG(I)p Fz(S)30 b FL(pro)o(vides)25 b(tw)o(o)h(programs)e
+Fp(pmetis)i FL(and)g Fp(kmetis)f FL(for)h(partitioning)e(an)i
+(unstructured)d(graph)i(into)h Ft(k)32 b FL(equal)25
+b(size)i(parts.)0 1196 y(The)c(partitioning)f(algorithm)h(used)g(by)h
+Fp(pmetis)f FL(is)i(based)e(on)g(multile)n(v)o(el)g(recursi)n(v)o(e)g
+(bisection)g(described)f(in)i([8)o(],)h(whereas)f(the)0
+1305 y(partitioning)j(algorithm)h(used)h(by)f Fp(kmetis)h
+FL(is)h(based)f(on)g(multile)n(v)o(el)f Ft(k)5 b FL(-w)o(ay)29
+b(partitioning)e(described)h(in)h([7)o(].)52 b(Both)29
+b(of)g(these)0 1415 y(programs)24 b(are)i(able)g(to)g(produce)e(high)h
+(quality)g(partitions.)41 b(Ho)n(we)n(v)o(er)m(,)26 b(depending)d(on)i
+(the)h(application,)g(one)f(program)f(may)i(be)0 1524
+y(preferable)16 b(than)i(the)g(other)-5 b(.)23 b(In)18
+b(general,)f Fp(kmetis)h FL(is)h(preferred)c(when)j(it)g(is)h
+(necessary)f(to)g(partition)f(graphs)g(into)g(more)g(than)h(eight)0
+1634 y(partitions.)37 b(F)o(or)25 b(such)f(cases,)i Fp(kmetis)e
+FL(is)i(considerably)c(f)o(aster)j(than)f Fp(pmetis)p
+FL(.)38 b(On)24 b(the)h(other)f(hand,)g Fp(pmetis)g FL(is)i(preferable)
+0 1744 y(for)20 b(partitioning)e(a)i(graph)f(into)h(a)h(small)f(number)
+f(of)h(partitions.)100 1853 y(Both)g Fp(pmetis)f FL(and)h
+Fp(kmetis)g FL(are)g(in)m(v)n(ok)o(ed)e(by)i(pro)o(viding)d(tw)o(o)k
+(ar)o(guments)d(at)j(the)f(command)e(line)i(as)h(follo)n(ws:)257
+2046 y FB(pmetis)124 b Fs(Gr)o(aphF)l(ile)f(Nparts)257
+2155 y FB(kmetis)129 b Fs(Gr)o(aphF)l(ile)123 b(Nparts)100
+2348 y FL(The)30 b(\002rst)h(ar)o(gument)e Fs(Gr)o(aphF)l(ile)p
+FL(,)j(is)f(the)g(name)f(of)g(the)h(\002le)g(that)g(stores)g(the)f
+(graph)f(\(whose)h(format)g(is)h(described)f(in)g(Sec-)0
+2458 y(tion)19 b(4.5.1\),)f(while)i(the)f(second)g(ar)o(gument)e
+Fs(Nparts)p FL(,)j(is)h(the)e(number)f(of)h(partitions)g(that)h(is)g
+(desired.)k(Both)c Fp(pmetis)f FL(and)g Fp(kmetis)0 2567
+y FL(can)i(partition)g(a)h(graph)e(into)h(an)g(arbitrary)f(number)g(of)
+h(partitions.)28 b(Upon)21 b(successful)g(e)o(x)o(ecution,)e(both)i
+(programs)f(display)h(statis-)0 2677 y(tics)i(re)o(garding)c(the)j
+(quality)f(of)h(the)g(computed)e(partitioning)f(and)j(the)g(amount)e
+(of)i(time)g(tak)o(en)g(to)g(perform)e(the)i(partitioning.)28
+b(The)0 2786 y(actual)20 b(partitioning)e(is)j(stored)f(in)g(a)h
+(\002le)g(named)e Fo(GraphF)m(ile.part.Nparts)p FL(,)f(whose)i(format)f
+(is)j(described)c(in)j(Section)f(4.6.1.)100 2896 y(Figure)k(3)h(sho)n
+(ws)g(the)g(output)f(of)g Fp(pmetis)h FL(and)f Fp(kmetis)h
+FL(for)f(partitioning)f(a)i(graph)f(into)h(100)f(parts.)39
+b(From)24 b(this)i(\002gure)e(we)0 3006 y(see)19 b(that)g(both)e
+(programs)g(initially)h(print)g(information)e(about)i(the)g(graph,)f
+(such)i(as)g(its)g(name,)f(the)h(number)d(of)j(v)o(ertices)f(\()p
+Fs(#V)-9 b(ertices)p FL(\),)0 3115 y(the)22 b(number)f(of)h(edges)g(\()
+p Fs(#Edg)o(es)p FL(\),)f(and)g(also)i(the)f(number)f(of)h(desired)f
+(partitions)h(\()p Fs(#P)-7 b(arts)p FL(\).)30 b(Ne)o(xt,)23
+b(the)o(y)e(print)h(some)g(information)0 3225 y(re)o(garding)h(the)j
+(quality)f(of)h(the)g(partitioning.)40 b(Speci\002cally)-5
+b(,)26 b(the)o(y)g(report)e(the)i(number)f(of)g(edges)h(being)f(cut)h
+(\()p Fs(Edg)o(e-Cut)p FL(\))e(by)i(the)0 3334 y(partitioning,)j(as)g
+(well)g(as)h(the)e(balance)g(of)h(the)f(partitioning)1841
+3304 y Fn(1)1875 3334 y FL(.)51 b(Finally)-5 b(,)30 b(both)d
+Fp(pmetis)i FL(and)f Fp(kmetis)g FL(sho)n(w)g(the)h(time)g(tak)o(en)0
+3444 y(by)e(the)g(v)n(arious)f(phases)h(of)g(the)g(algorithm.)44
+b(All)27 b(times)h(are)f(in)g(seconds.)45 b(F)o(or)27
+b(this)g(particular)f(e)o(xample,)h Fp(pmetis)g FL(required)e(a)0
+3553 y(total)g(of)g(17.070)d(seconds,)j(of)g(which)f(13.850)f(seconds)h
+(w)o(as)i(tak)o(en)e(by)h(the)g(partitioning)e(algorithm)g(itself,)j
+(and)f(the)f(rest)i(w)o(as)f(to)0 3663 y(read)d(the)g(graph)f(itself.)
+31 b(Similarly)-5 b(,)22 b Fp(kmetis)g FL(required)e(a)j(total)f(of)g
+(6.790)e(seconds,)i(of)g(which)g(3.570)e(seconds)i(w)o(as)h(tak)o(en)f
+(by)g(the)0 3773 y(partitioning)e(algorithm)g(itself.)31
+b(As)23 b(you)e(can)h(see)g(from)f(this)i(e)o(xample,)d
+Fp(kmetis)i FL(is)h(considerably)c(f)o(aster)j(than)g
+Fp(pmetis)p FL(,)f(and)h(it)0 3882 y(produces)c(a)j(partitioning)d
+(that)j(is)g(slightly)f(better)f(than)h(that)g(produced)e(by)i
+Fp(pmetis)p FL(.)100 3992 y(Figure)e(4)g(sho)n(ws)h(the)f(output)g(of)g
+Fp(pmetis)g FL(and)g Fp(kmetis)g FL(for)g(partitioning)f(a)i(graph)e
+(into)h(16)g(parts)h(subject)f(to)h(three)f(balancing)0
+4101 y(constraints.)41 b(Both)26 b Fp(pmetis)f FL(and)h
+Fp(kmetis)f FL(ha)n(v)o(e)g(been)g Fs(o)o(ver)n(-loaded)f
+FL(to)i(in)m(v)n(ok)o(e)f(the)h(multi-constraint)e(partitioning)g
+(routines)0 4211 y(whene)n(v)o(er)c(the)i(input)g(graph)e(\002le)j
+(speci\002es)g(more)e(that)h(one)g(set)h(of)f(v)o(erte)o(x)f(weights.)
+30 b(Comparing)21 b(the)h(output)f(of)g(Figure)h(4)g(to)g(that)0
+4321 y(of)c(Figure)f(3)h(we)g(see)h(that)f(when)f Fp(pmetis)h
+FL(and)f Fp(kmetis)h FL(operate)e(in)j(the)f(multi-constraint)d(mode)i
+(the)o(y)h(display)f(some)h(additional)0 4430 y(information)d(re)o
+(garding)g(the)j(number)e(of)i(constraints)f(and)h(also)g(the)g
+(balance)f(of)g(the)h(computed)e(partitioning)g(with)i(respect)g(to)g
+(each)0 4540 y(one)j(of)h(these)g(constraints.)28 b(In)22
+b(this)g(e)o(xample,)f Fp(pmetis)g FL(w)o(as)h(able)g(to)g(balance)f
+(the)g(three)h(constraints)f(within)g(1\045,)h(3\045,)g(and)g(2\045,)0
+4649 y(respecti)n(v)o(ely)-5 b(.)22 b(Note)c(that)g(for)g
+(multi-constraint)e(partitioning,)g(for)h(small)i(number)d(of)i
+(partitions)f Fp(pmetis)h FL(outperforms)d Fp(kmetis)0
+4759 y FL(in)20 b(terms)h(of)f(partitioning)e(quality)-5
+b(.)24 b(Ho)n(we)n(v)o(er)m(,)18 b(for)i(lar)o(ger)f(number)f(of)i
+(partitions)g Fp(kmetis)g FL(achie)n(v)o(es)f(better)h(quality)f(and)h
+(is)h(more)0 4869 y(rob)n(ust)f(in)g(simultaneously)f(balancing)f(the)i
+(v)n(arious)f(constraints.)p 0 5031 1560 4 v 87 5091
+a Fm(1)120 5115 y FF(F)o(or)d(a)h Fk(k)k FF(w)o(ay)c(partition)j(of)c
+(a)h(graph)h(with)f Fk(n)j FF(v)o(ertices,)f(let)e Fk(m)k
+FF(be)c(the)g(size)h(of)f(the)g(lar)o(gest)h(part)g(produced)g(by)f
+(the)h Fk(k)5 b FF(-w)o(ay)17 b(partitioning)j(algorithm.)j(The)16
+b(balance)0 5194 y(of)i(the)h(partitioning)i(is)d(de\002ned)h(as)f
+Fk(k)5 b(m)t Fl(=)t Fk(n)s FF(,)17 b(and)i(is)f(essentially)j(the)d
+(load)h(imbalance)i(induced)f(by)e(non-equal)i(partitions.)26
+b Fj(pmetis)17 b FF(produces)i(partitions)i(that)e(are)0
+5273 y(perfectly)h(balanced)g(at)d(each)i(bisection)g(le)n(v)o(el,)g
+(ho)n(we)n(v)o(er)m(,)g(some)e(small)h(load)g(imbalance)i(may)d(result)
+h(due)g(to)g(the)f(log)12 b Fk(k)22 b FF(le)n(v)o(els)d(of)e(recursi)n
+(v)o(e)i(bisection.)24 b(In)17 b(general,)0 5352 y(the)g(load)g
+(imbalance)h(is)e(less)h(than)f(1\045.)21 b Fj(kmetis)15
+b FF(produces)i(partitions)i(that)e(are)f(not)h(perfectly)i(balanced,)f
+(b)o(ut)e(the)h(algorithm)h(limits)f(the)g(load)g(imbalance)h(to)f
+(3\045.)1929 5649 y FL(8)p eop
+%%Page: 9 9
+9 8 bop 478 90 a Fi(')p 478 2466 7 2214 v 478 2635 a(&)3415
+90 y($)p 3415 2466 V 3415 2635 a(\045)p 648 2635 2605
+7 v 648 90 V 590 159 a Fj(prompt\045)39 b(pmetis)f(brack2.graph)h(100)
+590 237 y(******************************************)o(*******)o
+(******)o(*******)o(*******)o(*)669 316 y(METIS)h(4.0)119
+b(Copyright)38 b(1998,)h(Regents)g(of)h(the)f(University)f(of)i
+(Minnesota)590 474 y(Graph)f(Information)f
+(--------------------------------------------)o(-------)669
+553 y(Name:)i(brack2.graph,)d(#Vertices:)i(62631,)g(#Edges:)g(366559,)f
+(#Parts:)h(100)590 711 y(Recursive)f(Partitioning...)g
+(-------------------------------------------)669 790
+y(100-way)h(Edge-Cut:)118 b(37494,)39 b(Balance:)79 b(1.00)590
+947 y(Timing)39 b(Information)f
+(-------------------------------------------)o(-------)669
+1026 y(I/O:)1155 b(0.820)669 1105 y(Partitioning:)795
+b(6.110)119 b(\(PMETIS)39 b(time\))669 1184 y(Total:)1075
+b(6.940)590 1263 y(******************************************)o
+(*******)o(******)o(*******)o(*******)o(*)590 1421 y(prompt\045)39
+b(kmetis)f(brack2.graph)h(100)590 1499 y
+(******************************************)o(*******)o(******)o
+(*******)o(*******)o(*)669 1578 y(METIS)h(4.0)119 b(Copyright)38
+b(1998,)h(Regents)g(of)h(the)f(University)f(of)i(Minnesota)590
+1736 y(Graph)f(Information)f
+(--------------------------------------------)o(-------)669
+1815 y(Name:)i(brack2.graph,)d(#Vertices:)i(62631,)g(#Edges:)g(366559,)
+f(#Parts:)h(100)590 1973 y(K-way)g(Partitioning...)e
+(-----------------------------------------------)669
+2052 y(100-way)i(Edge-Cut:)118 b(37310,)39 b(Balance:)79
+b(1.03)590 2209 y(Timing)39 b(Information)f
+(-------------------------------------------)o(-------)669
+2288 y(I/O:)1155 b(0.820)669 2367 y(Partitioning:)795
+b(1.750)119 b(\(KMETIS)39 b(time\))669 2446 y(Total:)1075
+b(2.570)590 2525 y(******************************************)o
+(*******)o(******)o(*******)o(*******)o(*)546 2871 y
+Fy(Figure)18 b(3)p FL(:)25 b Fx(Output)19 b(of)f Fp(pmetis)g
+Fx(and)h Fp(kmetis)e Fx(f)n(or)i(g)o(r)o(aph)g Fh(br)o(ac)n(k2.g)o(r)o
+(aph)g Fx(and)f(a)h(100-w)o(a)n(y)g(par)s(tition.)0 3055
+y Fr(4.2)100 b(Mesh)28 b(P)m(ar)r(titioning)g(Pr)n(ograms)2
+3214 y Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)34 b FL(pro)o(vides)28
+b(tw)o(o)i(programs)d Fp(partnmesh)i FL(and)g Fp(partdmesh)f
+FL(for)h(partitioning)f(meshes)h(\()p Fs(e)o(.g)o FL(.,)j(those)d
+(arising)h(in)f(\002nite)0 3324 y(element)20 b(or)g(\002nite)g(v)n
+(olume)g(methods\))e(into)j Ft(k)k FL(equal)20 b(size)h(parts.)k(These)
+20 b(programs)f(tak)o(e)h(as)h(input)f(the)g(element)g(node)f(array)h
+(of)g(the)0 3434 y(mesh)i(and)f(compute)f(a)j(partitioning)c(for)j
+(both)f(its)h(elements)g(and)f(its)i(nodes.)31 b Fz(M)l
+FG(E)-17 b Fz(T)g FG(I)p Fz(S)26 b FL(currently)21 b(supports)f(four)h
+(dif)n(ferent)f(types)i(of)0 3543 y(mesh)e(elements)g(which)g(are)g
+(triangles,)f(tetrahedra,)g(he)o(xahedra)e(\(bricks\),)i(and)h
+(quadrilaterals.)100 3653 y(These)j(programs)f(\002rst)j(con)m(v)o(ert)
+c(the)j(mesh)g(into)f(a)h(graph,)f(and)h(then)f(use)h
+Fp(kmetis)f FL(to)h(partition)f(this)h(graph.)34 b(The)24
+b(dif)n(ference)0 3762 y(between)g(these)h(tw)o(o)g(programs)e(is)j
+(that)f Fp(partnmesh)f FL(con)m(v)o(erts)f(the)i(mesh)g(into)f(a)i
+(nodal)e(graph)f(\()p Fs(i.e)p FL(.,)j(each)e(node)g(of)h(the)g(mesh)0
+3872 y(becomes)17 b(a)h(v)o(erte)o(x)f(of)g(the)h(graph\),)e(whereas)i
+Fp(partdmesh)f FL(con)m(v)o(erts)f(the)i(mesh)f(into)h(a)g(dual)g
+(graph)e(\()p Fs(i.e)o FL(.,)j(each)e(element)h(becomes)0
+3981 y(a)f(v)o(erte)o(x)f(of)h(the)g(graph\).)22 b(In)17
+b(the)g(case)g(of)g Fp(partnmesh)p FL(,)g(the)g(partitioning)e(of)i
+(the)g(nodal)f(graph)f(is)j(used)f(to)g(deri)n(v)o(e)f(a)i
+(partitioning)d(of)0 4091 y(the)h(elements.)23 b(In)16
+b(the)g(case)g(of)f Fp(partdmesh)p FL(,)h(the)g(partitioning)e(of)h
+(the)h(dual)f(graph)g(is)i(used)e(to)h(deri)n(v)o(e)f(a)h(partitioning)
+e(of)i(the)g(nodes.)0 4201 y(Both)21 b(of)f(these)h(programs)e(produce)
+f(partitioning)h(of)h(comparable)f(quality)-5 b(,)19
+b(with)i Fp(partnmesh)e FL(being)h(considerably)e(f)o(aster)j(than)0
+4310 y Fp(partdmesh)p FL(.)41 b(Ho)n(we)n(v)o(er)m(,)25
+b(in)h(some)g(cases,)h Fp(partnmesh)e FL(may)g(produce)f(partitions)h
+(that)h(ha)n(v)o(e)g(higher)e(load)h(imbalance)g(than)0
+4420 y Fp(partdmesh)p FL(.)100 4529 y(Both)20 b Fp(partnmesh)f
+FL(and)h Fp(partdmesh)f FL(are)h(in)m(v)n(ok)o(ed)e(by)i(pro)o(viding)d
+(tw)o(o)k(ar)o(guments)d(at)j(the)f(command)e(line)i(as)h(follo)n(ws:)
+257 4722 y FB(par)r(tnmesh)124 b Fs(MeshF)l(ile)g(Nparts)257
+4832 y FB(par)r(tdmesh)g Fs(MeshF)l(ile)g(Nparts)100
+5024 y FL(The)15 b(\002rst)i(ar)o(gument)c Fs(MeshF)l(ile)p
+FL(,)k(is)g(the)f(name)f(of)g(the)h(\002le)h(that)e(stores)i(the)e
+(mesh)h(\(whose)f(format)g(is)i(described)d(in)i(Section)g(4.5.2\),)0
+5134 y(while)h(the)f(second)g(ar)o(gument)e Fs(Nparts)p
+FL(,)j(is)h(the)e(number)f(of)h(partitions)g(that)g(is)i(desired.)23
+b(Both)16 b Fp(partnmesh)g FL(and)f Fp(partdmesh)h FL(can)0
+5243 y(partition)24 b(a)i(mesh)f(into)g(an)g(arbitrary)e(number)h(of)h
+(partitions.)39 b(Upon)24 b(successful)h(e)o(x)o(ecution,)f(both)g
+(programs)f(display)i(statistics)0 5353 y(re)o(garding)h(the)j(quality)
+g(of)g(the)g(computed)e(partitioning)g(and)i(the)g(amount)f(of)h(time)g
+(tak)o(en)g(to)h(perform)d(the)i(partitioning.)50 b(The)1929
+5649 y(9)p eop
+%%Page: 10 10
+10 9 bop 478 90 a Fi(')p 478 2624 7 2372 v 478 2793 a(&)3415
+90 y($)p 3415 2624 V 3415 2793 a(\045)p 648 2793 2605
+7 v 648 90 V 590 159 a Fj(prompt\045)39 b(pmetis)f(m14.graph3)h(16)590
+237 y(******************************************)o(*******)o(******)o
+(*******)o(*******)o(*)669 316 y(METIS)h(4.0)119 b(Copyright)38
+b(1998,)h(Regents)g(of)h(the)f(University)f(of)i(Minnesota)590
+474 y(Graph)f(Information)f
+(--------------------------------------------)o(-------)669
+553 y(Name:)i(m14.graph3,)e(#Vertices:)g(214765,)h(#Edges:)g(1679018,)f
+(#Parts:)h(16)669 632 y(Balancing)g(Constraints:)f(3)590
+790 y(Recursive)g(Partitioning...)g
+(-------------------------------------------)669 868
+y(16-way)h(Edge-Cut:)119 b(74454,)39 b(Balance:)78 b(1.01)h(1.03)g
+(1.02)590 1026 y(Timing)39 b(Information)f
+(-------------------------------------------)o(-------)669
+1105 y(I/O:)1155 b(4.310)669 1184 y(Partitioning:)756
+b(28.410)118 b(\(PMETIS)39 b(time\))669 1263 y(Total:)1036
+b(32.830)590 1342 y(******************************************)o
+(*******)o(******)o(*******)o(*******)o(*)590 1499 y(prompt\045)39
+b(kmetis)f(m14.graph3)h(16)590 1578 y
+(******************************************)o(*******)o(******)o
+(*******)o(*******)o(*)669 1657 y(METIS)h(4.0)119 b(Copyright)38
+b(1998,)h(Regents)g(of)h(the)f(University)f(of)i(Minnesota)590
+1815 y(Graph)f(Information)f
+(--------------------------------------------)o(-------)669
+1894 y(Name:)i(m14.graph3,)e(#Vertices:)g(214765,)h(#Edges:)g(1679018,)
+f(#Parts:)h(16)669 1973 y(Balancing)g(Constraints:)f(3)590
+2130 y(K-way)h(Partitioning...)e
+(-----------------------------------------------)669
+2209 y(16-way)i(Edge-Cut:)119 b(71410,)39 b(Balance:)78
+b(1.04)h(1.04)g(1.04)590 2367 y(Timing)39 b(Information)f
+(-------------------------------------------)o(-------)669
+2446 y(I/O:)1155 b(4.020)669 2525 y(Partitioning:)795
+b(7.430)119 b(\(KMETIS)39 b(time\))669 2604 y(Total:)1036
+b(11.550)590 2682 y(******************************************)o
+(*******)o(******)o(*******)o(*******)o(*)172 3028 y
+Fy(Figure)18 b(4)p FL(:)26 b Fx(Output)18 b(of)h Fp(pmetis)f
+Fx(and)g Fp(kmetis)g Fx(f)n(or)h(a)f(m)o(ulti-constr)o(aint)h(g)o(r)o
+(aph)f(with)h(three)g(constr)o(aints)f(and)h(a)f(16-w)o(a)n(y)h(par)s
+(tition.)0 3213 y FL(actual)f(partitioning)f(is)j(stored)e(in)h(tw)o(o)
+g(\002les)g(named:)24 b Fo(MeshF)m(ile.npart.Nparts)18
+b FL(which)g(stores)h(the)f(partitioning)f(of)h(the)h(nodes,)f(and)0
+3322 y Fo(MeshF)m(ile.epart.Nparts)j FL(which)f(stores)i(the)f
+(partitioning)f(of)h(the)g(elements.)28 b(The)21 b(format)f(of)i(the)f
+(partitioning)e(\002les)k(is)f(described)0 3432 y(in)e(Section)g
+(4.6.1.)100 3541 y(Figure)d(5)g(sho)n(ws)h(the)g(output)e(of)h
+Fp(partnmesh)g FL(and)g Fp(partdmesh)f FL(for)h(partitioning)f(a)i
+(mesh)f(with)h(tetrahedron)d(elements)j(into)0 3651 y(100)h(parts.)25
+b(From)20 b(this)h(\002gure)e(we)i(see)f(that)h(both)e(programs)f
+(initially)j(print)e(information)f(about)h(the)h(mesh,)g(such)g(as)h
+(its)g(name,)f(the)0 3761 y(number)d(of)i(elements)f(\()p
+Fs(#Elements)p FL(\),)g(the)h(number)e(of)h(nodes)g(\()p
+Fs(#Nodes)p FL(\),)g(and)g(the)h(type)g(of)f(elements)h(\()p
+Fs(e)o(.g)n FL(.,)h Fs(TET)p FL(\).)e(Ne)o(xt,)h(the)o(y)f(print)0
+3870 y(some)27 b(information)d(re)o(garding)g(the)j(quality)f(of)h(the)
+f(partitioning.)43 b(Speci\002cally)-5 b(,)28 b(the)o(y)e(report)g(the)
+h(number)e(of)h(edges)h(being)f(cut)0 3980 y(\()p Fs(Edg)o(e-Cut)p
+FL(\))21 b(by)h(the)h(partitioning)1017 3950 y Fn(2)1050
+3980 y FL(,)h(as)g(well)f(as)h(the)e(balance)g(of)h(the)g
+(partitioning.)31 b(F)o(or)22 b(both)g Fp(partnmesh)g
+FL(and)g Fp(partdmesh)p FL(,)0 4089 y(the)h(balance)e(is)j(computed)c
+(with)j(respect)f(to)h(the)f(number)f(of)h(elements.)32
+b(The)22 b(balance)g(with)g(respect)h(to)f(the)h(number)e(of)h(nodes)g
+(is)0 4199 y(not)e(sho)n(wn,)f(b)n(ut)h(it)h(is)g(in)g(general)e
+(similar)h(to)g(the)h(element)e(balance.)100 4309 y(Finally)-5
+b(,)20 b(both)h Fp(partnmesh)f FL(and)g Fp(partdmesh)g
+FL(sho)n(w)h(the)g(time)h(that)f(w)o(as)h(tak)o(en)e(by)h(the)g(v)n
+(arious)f(phases)h(of)g(the)g(algorithm.)0 4418 y(All)k(times)h(are)e
+(in)h(seconds.)38 b(In)25 b(this)g(particular)f(e)o(xample,)g(it)h
+(took)f Fp(partnmesh)g FL(23.370)f(seconds)h(to)h(partition)e(the)i
+(mesh)g(into)0 4528 y(100)17 b(parts.)25 b(Note)18 b(that)g(this)h
+(time)f(includes)g(the)g(time)g(required)f(both)g(to)i(construct)e(the)
+h(nodal)f(graph)g(and)h(to)g(partition)g(it.)25 b(Similarly)-5
+b(,)0 4637 y(it)24 b(took)f Fp(partdmesh)g FL(74.560)e(seconds)i(to)h
+(partition)e(the)i(same)g(mesh.)35 b(Again,)23 b(this)h(time)g
+(includes)f(the)g(time)h(required)e(both)g(to)0 4747
+y(construct)j(the)h(dual)g(graph)e(and)i(to)g(partition)f(it.)43
+b(As)27 b(you)f(can)f(see)i(from)e(this)i(e)o(xample,)f
+Fp(partnmesh)f FL(is)i(considerably)c(f)o(aster)0 4857
+y(than)g Fp(partdmesh)p FL(.)32 b(This)23 b(is)h(because)e(of)h(tw)o(o)
+g(reasons:)31 b(\(i\))23 b(the)g(time)g(required)e(to)i(construct)f
+(the)h(nodal)f(graph)g(is)i(smaller)f(than)0 4966 y(the)d(time)h
+(required)d(to)i(construct)f(the)i(dual)e(graph;)g(\(ii\))h(the)h
+(nodal)e(graph)g(is)i(smaller)f(than)g(the)g(dual)g(graph.)p
+0 5129 1560 4 v 87 5189 a Fm(2)120 5213 y FF(The)15 b(edgecut)j(that)f
+(is)f(reported)i(by)e Fj(partnmesh)e FF(is)h(that)i(of)f(the)h(nodal)g
+(graph,)f(whereas)h(the)g(edgecut)h(reported)f(by)f Fj(partdmesh)e
+FF(is)i(that)h(of)f(the)g(dual)h(graph.)0 5292 y(These)g(tw)o(o)h
+(edgecuts)h(cannot)f(be)g(compared)g(with)g(each)g(other)m(,)g(as)f
+(the)o(y)h(correspond)h(to)e(partitionings)k(of)16 b(tw)o(o)i(totally)h
+(dif)n(ferent)h(graphs.)1908 5649 y FL(10)p eop
+%%Page: 11 11
+11 10 bop -18 83 a FB(Note)41 b FL(If)23 b(you)g(need)h(to)g(compute)e
+(multiple)h(partitionings)g(of)g(the)h(same)g(mesh,)h(it)g(may)e(be)h
+(preferable)e(to)i(\002rst)h(use)f(one)f(of)208 193 y(the)18
+b(mesh)f(con)m(v)o(ersion)f(programs)g(described)h(in)h(Section)f(4.4)h
+(to)g(\002rst)h(con)m(v)o(ert)d(the)i(mesh)g(into)f(a)i(graph,)e(and)g
+(then)h(use)208 302 y Fp(kmetis)h FL(to)i(partition)e(it.)25
+b(By)c(doing)e(this,)h(you)g(pay)f(the)h(cost)h(of)f(con)m(v)o(erting)d
+(the)j(mesh)g(into)g(a)h(graph)e(only)g(once.)478 555
+y Fi(')p 478 2772 7 2054 v 478 2941 a(&)3415 555 y($)p
+3415 2772 V 3415 2941 a(\045)p 648 2941 2605 7 v 648
+555 V 590 622 a Fj(prompt\045)39 b(partnmesh)f(144.mesh)h(100)590
+701 y(******************************************)o(*******)o(******)o
+(*******)o(*******)o(*)669 780 y(METIS)h(4.0)119 b(Copyright)38
+b(1998,)h(Regents)g(of)h(the)f(University)f(of)i(Minnesota)590
+938 y(Mesh)f(Information)f
+(---------------------------------------------)o(-------)669
+1016 y(Name:)i(144.mesh,)e(#Elements:)g(905410,)h(#Nodes:)g(144649,)g
+(Etype:)g(TET)590 1174 y(Partitioning)f(Nodal)h(Graph...)g
+(-----------------------------------------)669 1253 y(100-way)g
+(Edge-Cut:)79 b(105207,)38 b(Balance:)79 b(1.03)590 1411
+y(Timing)39 b(Information)f
+(-------------------------------------------)o(-------)669
+1490 y(I/O:)1116 b(13.210)669 1569 y(Partitioning:)795
+b(7.950)590 1647 y(******************************************)o
+(*******)o(******)o(*******)o(*******)o(*)590 1805 y(prompt\045)39
+b(partdmesh)f(144.mesh)h(100)590 1884 y
+(******************************************)o(*******)o(******)o
+(*******)o(*******)o(*)669 1963 y(METIS)h(4.0)119 b(Copyright)38
+b(1998,)h(Regents)g(of)h(the)f(University)f(of)i(Minnesota)590
+2121 y(Mesh)f(Information)f
+(---------------------------------------------)o(-------)669
+2199 y(Name:)i(144.mesh,)e(#Elements:)g(905410,)h(#Nodes:)g(144649,)g
+(Etype:)g(TET)590 2357 y(Partitioning)f(Dual)h(Graph...)g
+(------------------------------------------)669 2436
+y(100-way)g(Edge-Cut:)118 b(52474,)39 b(Balance:)79 b(1.03)590
+2594 y(Timing)39 b(Information)f
+(-------------------------------------------)o(-------)669
+2673 y(I/O:)1116 b(11.540)669 2752 y(Partitioning:)756
+b(28.220)590 2830 y(******************************************)o
+(*******)o(******)o(*******)o(*******)o(*)447 3176 y
+Fy(Figure)18 b(5)p FL(:)25 b Fx(Output)19 b(of)f Fp(partnmesh)f
+Fx(and)i Fp(partdmesh)e Fx(f)n(or)i(mesh)f Fh(144.mesh)h
+Fx(and)g(a)f(100-w)o(a)n(y)h(par)s(tition.)0 3491 y Fr(4.3)100
+b(Spar)o(se)29 b(Matrix)f(Reor)n(dering)f(Pr)n(ograms)102
+3647 y Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)27 b FL(pro)o(vides)20
+b(tw)o(o)j(programs)e Fp(oemetis)h FL(and)g Fp(onmetis)g
+FL(for)g(computing)e(\002ll-reducing)h(orderings)g(of)h(sparse)h
+(matrices.)0 3756 y(Both)d(of)f(these)h(programs)d(use)j(multile)n(v)o
+(el)e(nested)i(dissection)f(to)h(compute)e(a)i(\002ll-reducing)d
+(ordering)g([8].)25 b(The)19 b(nested)g(dissection)0
+3866 y(paradigm)k(is)j(based)f(on)f(computing)f(a)i(v)o(erte)o
+(x-separator)d(for)i(the)h(the)g(graph)e(corresponding)f(to)j(the)g
+(matrix.)39 b(The)24 b(nodes)g(in)i(the)0 3975 y(separator)18
+b(are)i(mo)o(v)o(ed)d(to)j(the)f(end)g(of)h(the)f(matrix,)g(and)g(a)h
+(similar)f(process)g(is)i(applied)d(recursi)n(v)o(ely)g(for)h(each)g
+(one)g(of)g(the)h(other)e(tw)o(o)0 4085 y(parts.)100
+4195 y(Ev)o(en)j(though)f(both)h(programs)f(are)i(based)g(on)g(multile)
+n(v)o(el)f(nested)h(dissection,)f(the)o(y)h(dif)n(fer)f(on)g(ho)n(w)h
+(the)o(y)f(compute)g(the)h(v)o(erte)o(x)0 4304 y(separators.)38
+b(The)24 b Fp(oemetis)g FL(program)f(\002nds)i(a)g(v)o(erte)o(x)e
+(separator)h(by)g(\002rst)h(computing)e(an)i(edge)f(separator)f(using)h
+(a)i(multile)n(v)o(el)0 4414 y(algorithm,)f(whereas)f(the)h
+Fp(onmetis)g FL(program)e(uses)j(the)f(multile)n(v)o(el)f(paradigm)f
+(to)i(directly)g(\002nd)g(a)g(v)o(erte)o(x)f(separator)-5
+b(.)39 b(The)25 b(or)n(-)0 4523 y(derings)20 b(produced)f(by)i
+Fp(onmetis)f FL(generally)g(incur)g(less)j(\002ll)f(than)f(those)g
+(produced)d(by)j Fp(oemetis)p FL(.)28 b(In)20 b(particular)m(,)g(for)h
+(matrices)0 4633 y(arising)g(in)g(linear)g(programming)d(problems)i
+(the)h(orderings)f(computed)f(by)i Fp(onmetis)f FL(are)h
+(signi\002cantly)g(better)g(than)g(those)g(pro-)0 4742
+y(duced)f(by)g Fp(oemetis)p FL(.)26 b(Furthermore,)18
+b Fp(onmetis)i FL(utilizes)i(compression)d(techniques)g(to)i(reduce)f
+(the)g(size)i(of)e(the)h(graph)f(prior)f(to)0 4852 y(computing)f(the)j
+(ordering.)j(Sparse)c(matrices)g(arising)g(in)h(man)o(y)e(application)g
+(domains)h(are)g(such)g(that)h(certain)f(ro)n(ws)g(of)h(the)f(matrix)0
+4962 y(ha)n(v)o(e)27 b(the)g(same)g(sparsity)g(pattern.)45
+b(Such)27 b(matrices)g(can)g(be)g(represented)e(by)i(a)h(much)e
+(smaller)h(graph)f(in)h(which)g(all)g(ro)n(ws)g(with)0
+5071 y(identical)d(sparsity)g(pattern)g(are)g(represented)f(by)h(just)h
+(a)g(single)g(v)o(erte)o(x)e(whose)h(weight)g(is)h(equal)f(to)h(the)f
+(number)f(of)h(ro)n(ws.)38 b(Such)0 5181 y(compression)21
+b(techniques)g(can)h(signi\002cantly)g(reduce)f(the)i(size)g(of)g(the)f
+(graph,)g(whene)n(v)o(er)e(applicable,)i(and)g(substantially)g(reduce)0
+5290 y(the)k(amount)f(of)g(time)i(required)d(by)h Fp(onmetis)p
+FL(.)42 b(Ho)n(we)n(v)o(er)m(,)25 b(when)h(there)f(is)i(no)f(reduction)
+e(in)i(graph)e(size,)k Fp(oemetis)e FL(is)h(about)0 5400
+y(20\045)19 b(to)h(30\045)f(f)o(aster)g(than)g Fp(onmetis)p
+FL(.)24 b(Furthermore,)17 b(for)i(lar)o(ge)f(matrices)h(arising)g(in)h
+(three-dimensional)c(problems,)i(the)h(quality)1908 5649
+y(11)p eop
+%%Page: 12 12
+12 11 bop 478 7 a Fi(')p 478 2541 7 2372 v 478 2710 a(&)3415
+7 y($)p 3415 2541 V 3415 2710 a(\045)p 648 2710 2605
+7 v 648 7 V 590 76 a Fj(prompt\045)39 b(oemetis)f(bcsstk31.graph)590
+154 y(******************************************)o(*******)o(******)o
+(*******)o(*******)o(*)669 233 y(METIS)i(4.0)119 b(Copyright)38
+b(1998,)h(Regents)g(of)h(the)f(University)f(of)i(Minnesota)590
+391 y(Graph)f(Information)f
+(--------------------------------------------)o(-------)669
+470 y(Name:)i(bcsstk31.graph,)d(#Vertices:)h(35588,)h(#Edges:)g(572914)
+590 628 y(Edge-Based)f(Ordering...)g
+(----------------------------------------------)669 707
+y(Nonzeros:)h(4693428,)158 b(Operation)39 b(Count:)g(1.4356e+09)590
+864 y(Timing)g(Information)f
+(-------------------------------------------)o(-------)669
+943 y(I/O:)1155 b(1.160)669 1022 y(Ordering:)955 b(7.380)119
+b(\(OEMETIS)39 b(time\))669 1101 y(Symbolic)g(Factorization:)396
+b(0.440)669 1180 y(Total:)1075 b(8.980)590 1259 y
+(******************************************)o(*******)o(******)o
+(*******)o(*******)o(*)590 1416 y(prompt\045)39 b(onmetis)f
+(bcsstk31.graph)590 1495 y(******************************************)o
+(*******)o(******)o(*******)o(*******)o(*)669 1574 y(METIS)i(4.0)119
+b(Copyright)38 b(1998,)h(Regents)g(of)h(the)f(University)f(of)i
+(Minnesota)590 1732 y(Graph)f(Information)f
+(--------------------------------------------)o(-------)669
+1811 y(Name:)i(bcsstk31.graph,)d(#Vertices:)h(35588,)h(#Edges:)g
+(572914)590 1968 y(Node-Based)f(Ordering...)g
+(----------------------------------------------)669 2047
+y(Nonzeros:)h(4330669,)158 b(Operation)39 b(Count:)g(1.1564e+09)590
+2205 y(Timing)g(Information)f
+(-------------------------------------------)o(-------)669
+2284 y(I/O:)1155 b(1.080)669 2363 y(Ordering:)955 b(4.540)119
+b(\(ONMETIS)39 b(time\))669 2442 y(Symbolic)g(Factorization:)396
+b(0.440)669 2521 y(Total:)1075 b(6.060)590 2599 y
+(******************************************)o(*******)o(******)o
+(*******)o(*******)o(*)826 2945 y Fy(Figure)18 b(6)p
+FL(:)25 b Fx(Output)19 b(of)f Fp(oemetis)g Fx(and)g Fp(onmetis)g
+Fx(f)n(or)g(g)o(r)o(aph)h Fh(bcsstk31.g)o(r)o(aph)q Fx(.)0
+3130 y FL(of)h(orderings)e(produced)g(by)i(the)g(tw)o(o)g(algorithms)f
+(is)i(quite)f(similar)-5 b(.)100 3239 y(Both)20 b Fp(oemetis)f
+FL(and)h Fp(onmetis)f FL(are)i(in)m(v)n(ok)o(ed)d(by)i(pro)o(viding)d
+(one)j(ar)o(gument)e(at)i(the)g(command)f(line)h(as)h(follo)n(ws:)257
+3432 y FB(oemetis)124 b Fs(Gr)o(aphF)l(ile)257 3541 y
+FB(onmetis)119 b Fs(Gr)o(aphF)l(ile)100 3734 y FL(The)23
+b(only)f(ar)o(gument)f(of)i(these)h(programs)d Fs(Gr)o(aphF)l(ile)p
+FL(,)i(is)i(the)e(name)g(of)g(the)g(\002le)h(that)g(stores)g(the)f
+(sparse)g(matrix)g(in)h(the)f(graph)0 3844 y(format)g(described)g(in)h
+(Section)f(4.5.1.)35 b(Upon)24 b(successful)f(e)o(x)o(ecution,)g(both)g
+(programs)f(display)i(statistics)h(re)o(garding)c(the)j(quality)0
+3953 y(of)19 b(the)f(computed)f(orderings)g(and)h(the)h(amount)e(of)i
+(time)g(tak)o(en)f(to)h(perform)e(the)i(ordering.)j(The)d(actual)f
+(ordering)f(is)i(stored)g(in)g(a)g(\002le)0 4063 y(named)g
+Fo(GraphF)m(ile.iperm)p FL(,)g(whose)h(format)f(is)i(described)e(in)i
+(Section)e(4.6.2.)100 4172 y(Figure)i(6)g(sho)n(ws)h(the)g(output)e(of)
+h Fp(oemetis)g FL(and)g Fp(onmetis)g FL(for)g(computing)f(a)i
+(\002ll-reducing)d(ordering)h(of)h(a)h(sample)f(matrix.)0
+4282 y(From)i(this)h(\002gure)f(we)h(see)g(that)f(both)g(programs)f
+(initially)h(print)g(information)e(about)i(the)g(graph,)g(such)h(as)g
+(its)g(name,)g(the)f(number)0 4392 y(of)e(v)o(ertices)g(\()p
+Fs(#V)-9 b(ertices)p FL(\),)20 b(and)g(the)i(number)d(of)i(edges)g(\()p
+Fs(#Edg)o(es)p FL(\).)26 b(Ne)o(xt,)21 b(the)o(y)f(print)g(some)h
+(information)e(re)o(garding)f(the)k(quality)e(of)0 4501
+y(the)f(ordering.)k(Speci\002cally)-5 b(,)18 b(the)o(y)g(report)g(the)h
+(number)f(of)g(non-zeros)f(that)j(are)f(required)e(in)i(the)g(lo)n(wer)
+g(triangular)f(matrix,)g(and)h(the)0 4611 y(number)e(of)i(operations)e
+(\()p Fs(OPC)p FL(\))i(required)e(to)i(f)o(actor)f(the)h(matrix)g
+(using)f(Cholesk)o(y)g(f)o(actorization.)23 b(Note)c(that)g(number)e
+(of)h(nonzeros)0 4720 y(includes)26 b(both)g(the)i(original)d
+(non-zeros)g(and)i(the)g(ne)n(w)g(non-zeros)e(due)h(to)h(the)g(\002ll.)
+46 b(Finally)-5 b(,)28 b(both)f Fp(oemetis)f FL(and)g
+Fp(onmetis)0 4830 y FL(sho)n(w)h(the)g(time)h(that)f(w)o(as)h(tak)o(en)
+f(by)g(the)g(v)n(arious)g(phases)g(of)g(the)g(algorithm.)45
+b(All)28 b(times)g(are)f(in)g(seconds.)46 b(F)o(or)27
+b(this)h(particular)0 4940 y(e)o(xample,)e Fp(oemetis)f
+FL(tak)o(es)i(a)f(total)g(of)g(23.290)e(seconds,)j(of)f(which)f(17.760)
+f(seconds)i(w)o(as)h(tak)o(en)e(by)h(the)g(ordering)e(algorithm)0
+5049 y(itself.)41 b(F)o(or)25 b(the)g(same)h(e)o(xample)e
+Fp(onmetis)g FL(tak)o(es)i(a)f(total)h(of)f(17.340)e(seconds,)j(of)f
+(which)g(11.810)e(seconds)i(w)o(as)h(tak)o(en)f(by)g(the)0
+5159 y(partitioning)d(algorithm)h(itself.)38 b(Note)24
+b(that)g(in)h(this)g(case)f Fp(onmetis)g FL(is)h(f)o(aster)f(than)g
+Fp(oemetis)p FL(,)g(because)g Fp(onmetis)g FL(w)o(as)h(able)0
+5268 y(to)20 b(compress)g(the)g(matrix.)k(Also)d(note)e(that)i(the)f
+(quality)f(of)h(the)g(\002ll-reducing)e(ordering)g(produced)g(by)i
+Fp(onmetis)f FL(is)i(signi\002cantly)0 5378 y(better)j(than)g(that)g
+(produced)e(by)i Fp(oemetis)p FL(.)37 b(In)24 b(f)o(act,)i(the)e
+(ordering)e(produced)g(by)i Fp(onmetis)g FL(results)h(in)f(8\045)h(fe)n
+(wer)f(non-zeros)1908 5649 y(12)p eop
+%%Page: 13 13
+13 12 bop 0 83 a FL(and)20 b(20\045)g(fe)n(wer)f(operations.)0
+314 y Fr(4.4)100 b(A)m(uxiliar)q(y)28 b(Pr)n(ograms)0
+470 y FB(4.4.1)84 b(Mesh)23 b(T)-7 b(o)23 b(Graph)f(Con)m(ver)o(sion)
+478 593 y Fi(')p 478 2809 7 2054 v 478 2979 a(&)3415
+593 y($)p 3415 2809 V 3415 2979 a(\045)p 648 2979 2605
+7 v 648 593 V 590 660 a Fj(prompt\045)39 b(mesh2nodal)f(144.mesh)590
+739 y(******************************************)o(*******)o(******)o
+(*******)o(*******)o(*)669 818 y(METIS)i(4.0)119 b(Copyright)38
+b(1998,)h(Regents)g(of)h(the)f(University)f(of)i(Minnesota)590
+975 y(Mesh)f(Information)f
+(---------------------------------------------)o(-------)669
+1054 y(Name:)i(144.mesh,)e(#Elements:)g(905410,)h(#Nodes:)g(144649,)g
+(Etype:)g(TET)590 1212 y(Forming)g(Nodal)g(Graph...)f
+(----------------------------------------------)669 1291
+y(Nodal)i(Information:)e(#Vertices:)g(144649,)h(#Edges:)g(1074393)590
+1449 y(Timing)g(Information)f
+(-------------------------------------------)o(-------)669
+1527 y(I/O:)1116 b(15.290)669 1606 y(Nodal)40 b(Creation:)715
+b(3.030)590 1685 y(******************************************)o
+(*******)o(******)o(*******)o(*******)o(*)590 1843 y(prompt\045)39
+b(mesh2dual)f(144.mesh)590 1922 y
+(******************************************)o(*******)o(******)o
+(*******)o(*******)o(*)669 2001 y(METIS)i(4.0)119 b(Copyright)38
+b(1998,)h(Regents)g(of)h(the)f(University)f(of)i(Minnesota)590
+2158 y(Mesh)f(Information)f
+(---------------------------------------------)o(-------)669
+2237 y(Name:)i(144.mesh,)e(#Elements:)g(905410,)h(#Nodes:)g(144649,)g
+(Etype:)g(TET)590 2395 y(Forming)g(Dual)g(Graph...)f
+(-----------------------------------------------)669
+2474 y(Dual)i(Information:)e(#Vertices:)g(905410,)h(#Edges:)g(1786484)
+590 2632 y(Timing)g(Information)f
+(-------------------------------------------)o(-------)669
+2710 y(I/O:)1116 b(19.200)669 2789 y(Dual)40 b(Creation:)716
+b(10.880)590 2868 y(******************************************)o
+(*******)o(******)o(*******)o(*******)o(*)785 3214 y
+Fy(Figure)18 b(7)p FL(:)25 b Fx(Output)19 b(of)g Fp(mesh2nodal)e
+Fx(and)h Fp(mesh2dual)f Fx(f)n(or)i(mesh)f Fh(144.mesh)q
+Fx(.)102 3408 y Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)27
+b FL(pro)o(vides)21 b(tw)o(o)j(programs)d Fp(mesh2nodal)h
+FL(and)g Fp(mesh2dual)g FL(for)h(con)m(v)o(erting)d(a)j(mesh)g(into)g
+(the)g(graph)f(format)g(used)0 3518 y(by)i Fz(M)l FG(E)-17
+b Fz(T)g FG(I)p Fz(S)r FL(.)24 b(In)e(particular)m(,)f
+Fp(mesh2nodal)g FL(con)m(v)o(erts)g(the)h(element)g(node)f(array)g(of)h
+(a)h(mesh)f(into)g(a)h(nodal)e(graph;)h Fs(i.e)p FL(.,)h(each)f(node)0
+3627 y(of)30 b(the)f(mesh)h(corresponds)e(to)i(a)g(v)o(erte)o(x)e(in)i
+(the)g(graph)e(and)i(tw)o(o)g(v)o(ertices)f(are)h(connected)e(by)h(an)h
+(edge)f(if)h(the)g(corresponding)0 3737 y(nodes)c(are)h(connected)d(by)
+j(lines)g(in)g(the)f(mesh.)45 b(Similarly)-5 b(,)27 b
+Fp(mesh2dual)f FL(con)m(v)o(erts)e(the)j(element)f(node)g(array)g(of)g
+(a)h(mesh)g(into)0 3847 y(a)g(dual)f(graph;)i Fs(i.e)p
+FL(.,)g(each)e(element)g(of)g(the)h(mesh)f(corresponds)f(to)h(a)h(v)o
+(erte)o(x)e(in)i(the)f(graph)f(and)h(tw)o(o)h(v)o(ertices)f(are)h
+(connected)d(if)0 3956 y(the)c(corresponding)d(elements)j(in)h(the)f
+(mesh)h(share)f(a)h(f)o(ace.)k(These)c(mesh-to-graph)c(con)m(v)o
+(ersion)g(programs)i(support)g(meshes)h(with)0 4066 y(triangular)m(,)e
+(tetrahedra,)g(and)i(he)o(xahedra)e(\(bricks\))h(elements.)100
+4175 y(Both)h Fp(mesh2nodal)f FL(and)g Fp(mesh2dual)g
+FL(are)i(in)m(v)n(ok)o(ed)d(by)i(pro)o(viding)d(one)j(ar)o(gument)e(at)
+i(the)h(command)d(line)i(as)h(follo)n(ws:)257 4349 y
+FB(mesh2nodal)124 b Fs(MeshF)l(ile)257 4459 y FB(mesh2dual)175
+b Fs(MeshF)l(ile)100 4633 y FL(The)30 b(only)h(ar)o(gument)d(of)j
+(these)g(programs)e Fs(MeshF)l(ile)p FL(,)34 b(is)e(the)f(name)g(of)f
+(the)h(\002le)h(that)f(stores)g(the)h(mesh)e(\(whose)h(format)f(is)0
+4742 y(described)15 b(in)h(Section)g(4.5.2\).)22 b(Upon)15
+b(successful)h(e)o(x)o(ecution,)f(both)g(programs)g(display)g
+(information)f(about)h(the)h(generated)f(graphs,)0 4852
+y(and)k(the)h(amount)f(of)g(time)h(tak)o(en)g(to)g(perform)e(the)i(con)
+m(v)o(ersion.)i(The)e(actual)f(graph)g(is)i(stored)e(in)h(a)g(\002le)h
+(named:)j Fo(MeshF)m(ile.ngraph)0 4962 y FL(in)g(the)g(case)g(of)f
+Fp(mesh2nodal)f FL(and)i Fo(MeshF)m(ile.dgraph)e FL(in)i(the)g(case)g
+(of)f Fp(mesh2dual)p FL(.)35 b(The)23 b(format)f(of)i(these)g(graph)e
+(\002les)j(are)0 5071 y(compatible)19 b(with)j Fz(M)l
+FG(E)-17 b Fz(T)g FG(I)p Fz(S)25 b FL(and)19 b(is)i(described)e(in)i
+(Section)e(4.5.1.)100 5181 y(Figure)e(7)g(sho)n(ws)h(the)g(output)e(of)
+i Fp(mesh2nodal)e FL(and)h Fp(mesh2dual)g FL(for)g(generating)f(the)h
+(nodal)g(and)g(dual)h(graphs)e(of)i(a)g(sample)0 5290
+y(mesh.)30 b(Note)22 b(that)g(the)g(sizes)h(of)e(the)h(generated)e
+(graphs)h(are)h(dif)n(ferent,)e(as)j(the)f(dual)f(graph)g(is)i(lar)o
+(ger)d(than)i(the)g(nodal)f(graph.)28 b(Also)0 5400 y(note)20
+b(that)g(generating)e(the)i(nodal)g(graph)e(is)k(considerably)c(f)o
+(aster)i(than)g(generating)e(the)i(dual)g(graph.)1908
+5649 y(13)p eop
+%%Page: 14 14
+14 13 bop 0 83 a FB(4.4.2)84 b(Graph)22 b(Chec)n(ker)2
+209 y Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)25 b FL(pro)o(vide)18
+b(a)j(program)d(called)j Fp(graphchk)e FL(to)i(check)f(whether)f(or)h
+(not)g(the)h(format)e(of)h(a)h(graph)e(is)j(appropriate)c(for)i(use)g
+(with)2 319 y Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r
+FL(.)24 b(This)e(program)e(should)h(be)h(used)g(whene)n(v)o(er)e(there)
+i(is)h(an)o(y)e(doubt)f(about)i(the)g(format)f(of)g(an)o(y)h(graph)e
+(\002le.)31 b(It)23 b(is)g(in)m(v)n(ok)o(ed)d(by)0 428
+y(pro)o(viding)d(one)j(ar)o(gument)e(at)j(the)f(command)e(line)i(as)h
+(follo)n(ws:)257 621 y FB(graphc)o(hk)124 b Fs(Gr)o(aphF)l(ile)0
+814 y FL(where)20 b Fs(Gr)o(aphF)l(ile)f FL(is)i(the)f(name)g(of)g(the)
+g(\002le)h(that)f(stores)g(the)h(graph.)1908 5649 y(14)p
+eop
+%%Page: 15 15
+15 14 bop 0 83 a Fr(4.5)100 b(Input)27 b(File)h(Formats)0
+242 y FL(The)d(v)n(arious)f(programs)g(in)k Fz(M)l FG(E)-17
+b Fz(T)g FG(I)p Fz(S)29 b FL(require)24 b(as)i(input)f(either)g(a)h
+(\002le)g(storing)f(a)h(graph)e(or)h(a)h(\002le)g(storing)e(a)i(mesh.)
+40 b(The)26 b(format)e(of)0 352 y(these)c(\002les)i(are)e(described)f
+(in)h(the)g(follo)n(wing)f(sections.)0 561 y FB(4.5.1)84
+b(Graph)22 b(File)0 687 y FL(The)j(primary)f(input)g(of)i(the)f
+(partitioning)e(and)i(\002ll-reducing)f(ordering)f(programs)g(in)28
+b Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)30 b FL(is)c(the)f(graph)f(to)i
+(be)f(partitioned)f(or)0 797 y(ordered.)f(This)d(graph)f(is)i(stored)f
+(in)g(a)h(\002le)g(and)e(is)j(supplied)d(to)h(the)g(v)n(arious)f
+(programs)g(as)i(one)e(of)h(the)g(command)f(line)h(parameters.)100
+907 y(A)i(graph)h Ft(G)32 b FM(D)26 b Fu(.)r Ft(V)8 b
+Fu(;)20 b Ft(E)7 b Fu(/)24 b FL(with)e Ft(n)k FL(v)o(ertices)c(and)f
+Ft(m)28 b FL(edges)22 b(is)h(stored)f(in)g(a)h(plain)f(te)o(xt)g
+(\002le)h(that)f(contains)f Ft(n)j FM(C)19 b FL(1)k(lines)f(\(e)o
+(xcluding)0 1016 y(comment)i(lines\).)40 b(The)25 b(\002rst)h(line)f
+(contains)g(information)e(about)h(the)h(size)h(and)f(the)g(type)g(of)g
+(the)g(graph,)g(while)g(the)g(remaining)f Ft(n)0 1126
+y FL(lines)d(contain)e(information)f(for)h(each)h(v)o(erte)o(x)f(of)j
+Ft(G)5 b FL(.)25 b(An)o(y)19 b(line)i(that)f(starts)h(with)f(`\045')h
+(is)g(a)f(comment)f(line)h(and)g(is)h(skipped.)100 1235
+y(The)g(\002rst)h(line)f(contains)g(either)g(tw)o(o)h(\()p
+Ft(n)s FL(,)g Ft(m)5 b FL(\),)21 b(three)g(\()p Ft(n)s
+FL(,)h Ft(m)5 b FL(,)22 b Fs(fmt)p FL(\),)g(or)f(four)f(\()p
+Ft(n)s FL(,)i Ft(m)5 b FL(,)22 b Fs(fmt)p FL(,)g Fs(ncon)p
+FL(\))e(inte)o(gers.)28 b(The)21 b(\002rst)h(tw)o(o)f(inte)o(gers)0
+1345 y(\()p Ft(n)s FL(,)f Ft(m)5 b FL(\))19 b(are)g(the)g(number)e(of)i
+(v)o(ertices)f(and)h(the)g(number)e(of)i(edges,)g(respecti)n(v)o(ely)-5
+b(.)22 b(Note)d(that)h(in)f(determining)e(the)i(number)e(of)i(edges)0
+1455 y Ft(m)5 b FL(,)26 b(an)e(edge)g(between)g(an)o(y)f(pair)h(of)h(v)
+o(ertices)f Fu(v)k FL(and)c Ft(u)29 b FL(is)d(counted)d
+FC(only)h(once)g FL(and)g(not)g(twice)h(\()p Fs(i.e)p
+FL(.,)g(we)g(do)f(not)g(count)g(the)g(edge)0 1564 y Fu(.v)s(;)14
+b Ft(u)t Fu(/)22 b FL(separately)e(from)g Fu(.)p Ft(u)t
+Fu(;)14 b(v)s(/)p FL(\).)28 b(F)o(or)20 b(e)o(xample,)f(the)i(graph)f
+(in)h(Figure)f(8)g(contains)h(11)f(v)o(ertices.)26 b(The)21
+b(third)f(inte)o(ger)f(\()p Fs(fmt)p FL(\))i(is)h(used)0
+1674 y(to)h(specify)g(whether)f(or)h(not)g(the)g(graph)f(has)i(weights)
+f(associated)g(with)g(its)h(v)o(ertices,)g(its)g(edges,)f(or)g(both.)33
+b(T)-7 b(able)24 b(2)f(describes)g(the)0 1783 y(possible)i(v)n(alues)g
+(of)h Fs(fmt)g FL(and)f(their)g(meaning.)40 b(Note)25
+b(that)h(if)g(the)g(graph)e(is)i(unweighted)e(\()p Fs(i.e)o
+FL(.,)j(all)f(v)o(ertices)f(and)g(edges)h(ha)n(v)o(e)f(the)0
+1893 y(same)d(weight\),)f(then)h(the)f Fs(fmt)j FL(parameter)d(can)g
+(be)h(omitted.)29 b(Finally)-5 b(,)22 b(the)g(fourth)e(inte)o(ger)h(\()
+p Fs(ncon)p FL(\))f(is)j(used)e(to)h(specify)g(the)f(number)0
+2003 y(of)e(weights)g(associated)f(with)i(each)e(v)o(erte)o(x)g(of)g
+(the)h(graph.)24 b(The)18 b(v)n(alue)h(of)f(this)i(parameter)d
+(determines)h(whether)g(or)h(not)i Fz(M)l FG(E)-17 b
+Fz(T)g FG(I)p Fz(S)23 b FL(will)0 2112 y(use)e(the)f(multi-constraint)e
+(partitioning)h(algorithms)g(described)g(in)i(Section)f(3.)26
+b(If)20 b(the)g(v)o(ertices)g(of)g(the)h(graph)e(ha)n(v)o(e)h(no)g
+(weights)g(or)0 2222 y(only)h(a)h(single)f(weight,)g(then)g(the)h
+Fs(ncon)f FL(parameter)f(can)h(be)g(omitted.)29 b(Ho)n(we)n(v)o(er)m(,)
+19 b(if)j Fs(ncon)f FL(is)h(greater)f(than)g(0,)h(then)f(the)g(\002le)i
+(should)0 2331 y(contain)18 b(the)h(required)f(v)o(erte)o(x)g(weights)h
+(and)f(the)h Fs(fmt)h FL(parameter)e(should)g(be)h(set)h(appropriately)
+d(\()p Fs(i.e)o FL(.,)j(it)f(should)g(be)g(set)h(to)f(either)g(10)0
+2441 y(or)h(11\).)p 590 2625 2721 4 v 588 2725 4 100
+v 640 2695 a Fs(fmt)p 794 2725 V 99 w FL(Meaning)p 3309
+2725 V 590 2728 2721 4 v 588 2828 4 100 v 672 2798 a(0)p
+794 2828 V 131 w(The)g(graph)f(has)h(no)g(weights)g(associated)g(with)h
+(either)e(the)i(edges)e(or)h(the)g(v)o(ertices)p 3309
+2828 V 590 2831 2721 4 v 588 2930 4 100 v 672 2901 a(1)p
+794 2930 V 131 w(The)g(graph)f(has)h(weights)g(associated)g(with)h(the)
+f(edges)p 3309 2930 V 590 2934 2721 4 v 588 3033 4 100
+v 651 3004 a(10)p 794 3033 V 110 w(The)g(graph)f(has)h(weights)g
+(associated)g(with)h(the)f(v)o(ertices)p 3309 3033 V
+590 3037 2721 4 v 588 3136 4 100 v 651 3106 a(11)p 794
+3136 V 110 w(The)g(graph)f(has)h(weights)g(associated)g(with)h(both)e
+(the)h(edges)g(&)g(v)o(ertices)p 3309 3136 V 590 3140
+2721 4 v 776 3292 a Fy(T)-5 b(ab)o(le)17 b(2)p FL(:)26
+b Fx(The)18 b(v)n(ar)q(ious)h(possib)o(le)f(v)n(alues)h(f)n(or)g(the)f
+Fh(fmt)h Fx(par)o(ameter)e(and)i(their)f(meaning.)100
+3571 y FL(The)f(remaining)g Ft(n)22 b FL(lines)c(store)h(information)c
+(about)j(the)g(actual)g(structure)f(of)h(the)g(graph.)23
+b(In)18 b(particular)m(,)f(the)g Ft(i)9 b FL(th)18 b(line)g(\(e)o
+(xcluding)0 3680 y(comment)25 b(lines\))h(contains)f(information)f
+(that)i(is)h(rele)n(v)n(ant)e(to)h(the)f Ft(i)9 b FL(th)26
+b(v)o(erte)o(x.)41 b(Depending)24 b(on)i(the)g(v)n(alue)f(of)h(the)g
+Fs(fmt)h FL(and)f Fs(ncon)0 3790 y FL(parameters,)d(the)h(information)e
+(stored)h(at)h(each)g(line)g(is)h(some)n(what)e(dif)n(ferent.)34
+b(In)23 b(the)h(most)g(general)f(form)g(\(when)g Fs(fmt)h(=)h(11)e
+FL(and)0 3899 y Fs(ncon)c Fu(>)i Fs(1)p FL(\))f(each)f(line)i(will)g
+(ha)n(v)o(e)e(the)h(follo)n(wing)f(structure:)1225 4100
+y Fu(w)1286 4112 y Fn(1)1322 4100 y Fu(;)14 b(w)1424
+4112 y Fn(2)1460 4100 y Fu(;)g(:)g(:)g(:)f(w)1672 4112
+y Ff(n)r(c)q(o)q(n)1806 4100 y Fu(;)38 b(v)1911 4112
+y Fn(1)1947 4100 y Fu(;)14 b Ft(e)2025 4112 y Fn(1)2061
+4100 y Fu(;)g(v)2142 4112 y Fn(2)2178 4100 y Fu(;)g Ft(e)2256
+4112 y Fn(2)2292 4100 y Fu(;)g(:)g(:)g(:)f(;)h(v)2524
+4112 y Ff(k)2561 4100 y Fu(;)g Ft(e)2639 4112 y Ff(k)0
+4301 y FL(where)20 b Fu(w)285 4313 y Fn(1)321 4301 y
+Fu(;)14 b(w)423 4313 y Fn(2)459 4301 y Fu(;)g(:)g(:)g(:)f(;)h(w)712
+4313 y Ff(n)r(c)q(o)q(n)869 4301 y FL(are)21 b(the)g
+Fs(ncon)f FL(v)o(erte)o(x)f(weights)i(associated)g(with)g(this)h(v)o
+(erte)o(x,)d Fu(v)2765 4313 y Fn(1)2801 4301 y Fu(;)14
+b(v)2882 4313 y Fn(2)2919 4301 y Fu(;)g(:)g(:)g(:)f(;)h(v)3151
+4313 y Ff(k)3210 4301 y FL(are)20 b(the)i(v)o(ertices)e(adja-)0
+4411 y(cent)h(to)f(this)h(v)o(erte)o(x,)f(and)g Ft(e)812
+4423 y Fn(1)847 4411 y Fu(;)14 b Ft(e)925 4423 y Fn(2)961
+4411 y Fu(;)g(:)g(:)g(:)f(;)h Ft(e)1190 4423 y Ff(k)1248
+4411 y FL(are)20 b(the)h(weights)f(of)h(these)g(edges.)k(In)c(the)f
+(remaining)f(of)i(this)g(section)f(we)h(illustrate)g(this)0
+4520 y(format)e(by)h(a)h(sequence)e(of)h(e)o(xamples.)k(Note)d(that)f
+(the)g(v)o(ertices)g(are)g(numbered)e(starting)i(from)g(1)g(\(not)g
+(from)f(0)h(as)h(is)h(often)d(done)g(in)0 4630 y(C\).)j(Furthermore,)d
+(the)i(v)o(erte)o(x-weights)e(must)i(be)h(inte)o(gers)e(greater)h(or)g
+(equal)g(to)g(0,)h(whereas)f(the)g(edge-weights)f(must)h(be)g(strictly)
+0 4740 y(greater)e(than)h(0.)100 4849 y(The)k(simplest)g(format)g(for)f
+(a)i(graph)g Ft(G)30 b FL(is)25 b(when)f(the)h(weight)e(of)i(all)f(v)o
+(ertices)g(and)g(the)h(weight)f(of)g(all)h(the)f(edges)g(is)h(the)g
+(same.)0 4959 y(This)20 b(format)f(is)j(illustrated)d(in)i(Figure)e
+(8\(a\).)24 b(Note,)c(the)h(optional)d Fs(fmt)23 b FL(parameter)18
+b(is)k(skipped)d(in)h(this)h(case.)100 5068 y(Ho)n(we)n(v)o(er)m(,)30
+b(there)g(are)g(cases)h(in)f(which)g(the)g(edges)g(in)i
+Ft(G)k FL(ha)n(v)o(e)30 b(dif)n(ferent)e(weights.)55
+b(This)30 b(is)i(accommodated)27 b(as)k(sho)n(wn)e(in)0
+5178 y(Figure)21 b(8\(b\).)30 b(No)n(w)-5 b(,)22 b(the)g(adjacenc)o(y)f
+(list)i(of)f(each)f(v)o(erte)o(x)g(contains)h(the)g(weight)f(of)h(the)g
+(edges)g(in)g(addition)f(to)i(the)f(v)o(ertices)f(that)i(is)0
+5288 y(connected)18 b(with.)25 b(If)20 b Fu(v)25 b FL(has)20
+b Ft(k)26 b FL(v)o(ertices)19 b(adjacent)g(to)i(it,)f(then)g(the)g
+(line)g(for)g Fu(v)k FL(in)c(the)g(graph)f(\002le)i(contains)e(2)f
+FM(\003)g Ft(k)26 b FL(numbers,)18 b(each)i(pair)0 5397
+y(of)j(numbers)f(stores)i(the)f(v)o(erte)o(x)f(that)i
+Fu(v)k FL(is)c(connected)e(to,)i(and)f(the)h(weight)f(of)g(the)g(edge.)
+35 b(Note)23 b(that)h(the)f Fs(fmt)j FL(parameter)c(is)i(equal)1908
+5649 y(15)p eop
+%%Page: 16 16
+16 15 bop 600 3819 a @beginspecial 0 @llx 0 @lly 673
+@urx 952 @ury 3240 @rwi @setspecial
+%%BeginDocument: ./figures/graph00.eps
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+-8.0 955.0 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+  bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+  4 -2 roll mul srgb} bind def
+/reencdict 12 dict def /ReEncode { reencdict begin
+/newcodesandnames exch def /newfontname exch def /basefontname exch def
+/basefontdict basefontname findfont def /newfont basefontdict maxlength dict def
+basefontdict { exch dup /FID ne { dup /Encoding eq
+{ exch dup length array copy newfont 3 1 roll put }
+{ exch newfont 3 1 roll put } ifelse } { pop pop } ifelse } forall
+newfont /FontName newfontname put newcodesandnames aload pop
+128 1 255 { newfont /Encoding get exch /.notdef put } for
+newcodesandnames length 2 idiv { newfont /Encoding get 3 1 roll put } repeat
+newfontname newfont definefont pop end } def
+/isovec [
+8#200 /grave 8#201 /acute 8#202 /circumflex 8#203 /tilde
+8#204 /macron 8#205 /breve 8#206 /dotaccent 8#207 /dieresis
+8#210 /ring 8#211 /cedilla 8#212 /hungarumlaut 8#213 /ogonek 8#214 /caron
+8#220 /dotlessi 8#230 /oe 8#231 /OE
+8#240 /space 8#241 /exclamdown 8#242 /cent 8#243 /sterling
+8#244 /currency 8#245 /yen 8#246 /brokenbar 8#247 /section 8#250 /dieresis
+8#251 /copyright 8#252 /ordfeminine 8#253 /guillemotleft 8#254 /logicalnot
+8#255 /endash 8#256 /registered 8#257 /macron 8#260 /degree 8#261 /plusminus
+8#262 /twosuperior 8#263 /threesuperior 8#264 /acute 8#265 /mu 8#266 /paragraph
+8#267 /periodcentered 8#270 /cedilla 8#271 /onesuperior 8#272 /ordmasculine
+8#273 /guillemotright 8#274 /onequarter 8#275 /onehalf
+8#276 /threequarters 8#277 /questiondown 8#300 /Agrave 8#301 /Aacute
+8#302 /Acircumflex 8#303 /Atilde 8#304 /Adieresis 8#305 /Aring
+8#306 /AE 8#307 /Ccedilla 8#310 /Egrave 8#311 /Eacute
+8#312 /Ecircumflex 8#313 /Edieresis 8#314 /Igrave 8#315 /Iacute
+8#316 /Icircumflex 8#317 /Idieresis 8#320 /Eth 8#321 /Ntilde 8#322 /Ograve
+8#323 /Oacute 8#324 /Ocircumflex 8#325 /Otilde 8#326 /Odieresis 8#327 /multiply
+8#330 /Oslash 8#331 /Ugrave 8#332 /Uacute 8#333 /Ucircumflex
+8#334 /Udieresis 8#335 /Yacute 8#336 /Thorn 8#337 /germandbls 8#340 /agrave
+8#341 /aacute 8#342 /acircumflex 8#343 /atilde 8#344 /adieresis 8#345 /aring
+8#346 /ae 8#347 /ccedilla 8#350 /egrave 8#351 /eacute
+8#352 /ecircumflex 8#353 /edieresis 8#354 /igrave 8#355 /iacute
+8#356 /icircumflex 8#357 /idieresis 8#360 /eth 8#361 /ntilde 8#362 /ograve
+8#363 /oacute 8#364 /ocircumflex 8#365 /otilde 8#366 /odieresis 8#367 /divide
+8#370 /oslash 8#371 /ugrave 8#372 /uacute 8#373 /ucircumflex
+8#374 /udieresis 8#375 /yacute 8#376 /thorn 8#377 /ydieresis] def
+/Times-BoldItalic /Times-BoldItalic-iso isovec ReEncode
+/Times-Roman /Times-Roman-iso isovec ReEncode
+/Helvetica-Bold /Helvetica-Bold-iso isovec ReEncode
+/Courier /Courier-iso isovec ReEncode
+/Helvetica /Helvetica-iso isovec ReEncode
+/Times-Bold /Times-Bold-iso isovec ReEncode
+/Helvetica-BoldOblique /Helvetica-BoldOblique-iso isovec ReEncode
+ /DrawEllipse {
+	/endangle exch def
+	/startangle exch def
+	/yrad exch def
+	/xrad exch def
+	/y exch def
+	/x exch def
+	/savematrix mtrx currentmatrix def
+	x y tr xrad yrad sc 0 0 1 startangle endangle arc
+	closepath
+	savematrix setmatrix
+	} def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+10 setmiterlimit
+n -1000 16912 m -1000 -1000 l 12337 -1000 l 12337 16912 l cp clip
+ 0.06000 0.06000 sc
+% Polyline
+7.500 slw
+n 826 3151 m 2026 2026 l gs col-1 s gr 
+% Polyline
+n 901 3151 m 2926 2926 l gs col-1 s gr 
+% Polyline
+n 2926 2926 m 2026 2026 l gs col-1 s gr 
+% Polyline
+n 901 1276 m 1951 526 l gs col-1 s gr 
+% Polyline
+n 1951 526 m 3226 1126 l gs col-1 s gr 
+% Polyline
+n 1951 526 m 2026 2026 l gs col-1 s gr 
+% Polyline
+n 2026 2026 m 976 1276 l gs col-1 s gr 
+% Polyline
+n 3226 1126 m 2926 2926 l gs col-1 s gr 
+% Polyline
+n 2926 2926 m 3976 2401 l gs col-1 s gr 
+% Polyline
+n 3976 2401 m 3226 1126 l gs col-1 s gr 
+% Polyline
+n 901 1276 m 826 3151 l gs col-1 s gr 
+% Polyline
+n 7352 11402 m 8552 10277 l gs col-1 s gr 
+% Polyline
+n 7427 11402 m 9452 11177 l gs col-1 s gr 
+% Polyline
+n 9452 11177 m 8552 10277 l gs col-1 s gr 
+% Polyline
+n 7427 9527 m 8477 8777 l gs col-1 s gr 
+% Polyline
+n 8477 8777 m 9752 9377 l gs col-1 s gr 
+% Polyline
+n 8477 8777 m 8552 10277 l gs col-1 s gr 
+% Polyline
+n 8552 10277 m 7502 9527 l gs col-1 s gr 
+% Polyline
+n 9752 9377 m 9452 11177 l gs col-1 s gr 
+% Polyline
+n 9452 11177 m 10502 10652 l gs col-1 s gr 
+% Polyline
+n 10502 10652 m 9752 9377 l gs col-1 s gr 
+% Polyline
+n 7427 9527 m 7352 11402 l gs col-1 s gr 
+% Polyline
+n 7126 3152 m 8326 2027 l gs col-1 s gr 
+% Polyline
+n 7201 3152 m 9226 2927 l gs col-1 s gr 
+% Polyline
+n 9226 2927 m 8326 2027 l gs col-1 s gr 
+% Polyline
+n 7201 1277 m 8251 527 l gs col-1 s gr 
+% Polyline
+n 8251 527 m 9526 1127 l gs col-1 s gr 
+% Polyline
+n 8251 527 m 8326 2027 l gs col-1 s gr 
+% Polyline
+n 8326 2027 m 7276 1277 l gs col-1 s gr 
+% Polyline
+n 9526 1127 m 9226 2927 l gs col-1 s gr 
+% Polyline
+n 9226 2927 m 10276 2402 l gs col-1 s gr 
+% Polyline
+n 10276 2402 m 9526 1127 l gs col-1 s gr 
+% Polyline
+n 7201 1277 m 7126 3152 l gs col-1 s gr 
+% Polyline
+n 977 11252 m 2177 10127 l gs col-1 s gr 
+% Polyline
+n 1052 11252 m 3077 11027 l gs col-1 s gr 
+% Polyline
+n 3077 11027 m 2177 10127 l gs col-1 s gr 
+% Polyline
+n 1052 9377 m 2102 8627 l gs col-1 s gr 
+% Polyline
+n 2102 8627 m 3377 9227 l gs col-1 s gr 
+% Polyline
+n 2102 8627 m 2177 10127 l gs col-1 s gr 
+% Polyline
+n 2177 10127 m 1127 9377 l gs col-1 s gr 
+% Polyline
+n 3377 9227 m 3077 11027 l gs col-1 s gr 
+% Polyline
+n 3077 11027 m 4127 10502 l gs col-1 s gr 
+% Polyline
+n 4127 10502 m 3377 9227 l gs col-1 s gr 
+% Polyline
+n 1052 9377 m 977 11252 l gs col-1 s gr 
+% Ellipse
+n 2008 2008 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 901 1276 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 1933 508 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 3208 1108 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 2908 2908 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 3958 2383 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 808 3133 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 8534 10259 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 7427 9527 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 8459 8759 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 9734 9359 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 9434 11159 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 10484 10634 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 7334 11384 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 8308 2009 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 7201 1277 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 8233 509 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 9508 1109 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 9208 2909 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 10258 2384 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 7108 3134 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 2159 10109 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 1052 9377 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 2084 8609 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 3359 9209 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 3059 11009 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 4109 10484 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+% Ellipse
+n 959 11234 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr
+
+/Helvetica-iso ff 210.00 scf sf
+1951 2101 m
+gs 1 -1 sc (3) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+2851 3001 m
+gs 1 -1 sc (4) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+1876 601 m
+gs 1 -1 sc (5) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+3151 1201 m
+gs 1 -1 sc (6) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+751 3226 m
+gs 1 -1 sc (2) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+3901 2476 m
+gs 1 -1 sc (7) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+863 1351 m
+gs 1 -1 sc (1) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+1202 4727 m
+gs 1 -1 sc (7 11) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+1202 4997 m
+gs 1 -1 sc (5 3 2) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+1202 5267 m
+gs 1 -1 sc (1 3 4) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+1202 5807 m
+gs 1 -1 sc (2 3 6 7) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+1202 6077 m
+gs 1 -1 sc (1 3 6) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+1202 6347 m
+gs 1 -1 sc (5 4 7) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+1202 6617 m
+gs 1 -1 sc (6 4) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+1202 5537 m
+gs 1 -1 sc (5 4 2 1) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+8477 10352 m
+gs 1 -1 sc (3) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+9377 11252 m
+gs 1 -1 sc (4) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+8402 8852 m
+gs 1 -1 sc (5) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+9677 9452 m
+gs 1 -1 sc (6) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+7277 11477 m
+gs 1 -1 sc (2) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+10427 10727 m
+gs 1 -1 sc (7) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+7389 9602 m
+gs 1 -1 sc (1) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+8251 2102 m
+gs 1 -1 sc (3) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+9151 3002 m
+gs 1 -1 sc (4) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+8176 602 m
+gs 1 -1 sc (5) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+9451 1202 m
+gs 1 -1 sc (6) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+7051 3227 m
+gs 1 -1 sc (2) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+10201 2477 m
+gs 1 -1 sc (7) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+7163 1352 m
+gs 1 -1 sc (1) col-1 sh gr
+/Times-Bold-iso ff 210.00 scf sf
+7651 827 m
+gs 1 -1 sc (1) col-1 sh gr
+/Times-Bold-iso ff 210.00 scf sf
+8926 752 m
+gs 1 -1 sc (2) col-1 sh gr
+/Times-Bold-iso ff 210.00 scf sf
+8401 1352 m
+gs 1 -1 sc (3) col-1 sh gr
+/Times-Bold-iso ff 210.00 scf sf
+7801 1577 m
+gs 1 -1 sc (2) col-1 sh gr
+/Times-Bold-iso ff 210.00 scf sf
+7726 2477 m
+gs 1 -1 sc (2) col-1 sh gr
+/Times-Bold-iso ff 210.00 scf sf
+8176 3002 m
+gs 1 -1 sc (1) col-1 sh gr
+/Times-Bold-iso ff 210.00 scf sf
+8776 2402 m
+gs 1 -1 sc (2) col-1 sh gr
+/Times-Bold-iso ff 210.00 scf sf
+9226 2027 m
+gs 1 -1 sc (2) col-1 sh gr
+/Times-Bold-iso ff 210.00 scf sf
+9676 2627 m
+gs 1 -1 sc (5) col-1 sh gr
+/Times-Bold-iso ff 210.00 scf sf
+9976 1727 m
+gs 1 -1 sc (6) col-1 sh gr
+/Times-Bold-iso ff 210.00 scf sf
+6976 2177 m
+gs 1 -1 sc (1) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+7502 4728 m
+gs 1 -1 sc (7 11 1) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+7502 4998 m
+gs 1 -1 sc (5 1 3 2 2 1) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+7502 5268 m
+gs 1 -1 sc (1 1 3 2 4 1) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+7502 5538 m
+gs 1 -1 sc (5 3 4 2 2 2 1 2) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+7502 5808 m
+gs 1 -1 sc (2 1 3 2 6 2 7 5) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+7502 6078 m
+gs 1 -1 sc (1 1 3 3 6 2) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+7502 6348 m
+gs 1 -1 sc (5 2 4 2 7 6) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+7502 6618 m
+gs 1 -1 sc (6 6 4 5) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+2102 10202 m
+gs 1 -1 sc (3) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+3002 11102 m
+gs 1 -1 sc (4) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+2027 8702 m
+gs 1 -1 sc (5) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+3302 9302 m
+gs 1 -1 sc (6) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+902 11327 m
+gs 1 -1 sc (2) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+4052 10577 m
+gs 1 -1 sc (7) col-1 sh gr
+/Helvetica-iso ff 210.00 scf sf
+1014 9452 m
+gs 1 -1 sc (1) col-1 sh gr
+/Times-Bold-iso ff 210.00 scf sf
+1502 8927 m
+gs 1 -1 sc (1) col-1 sh gr
+/Times-Bold-iso ff 210.00 scf sf
+2777 8852 m
+gs 1 -1 sc (2) col-1 sh gr
+/Times-Bold-iso ff 210.00 scf sf
+2252 9452 m
+gs 1 -1 sc (3) col-1 sh gr
+/Times-Bold-iso ff 210.00 scf sf
+1652 9677 m
+gs 1 -1 sc (2) col-1 sh gr
+/Times-Bold-iso ff 210.00 scf sf
+1577 10577 m
+gs 1 -1 sc (2) col-1 sh gr
+/Times-Bold-iso ff 210.00 scf sf
+2027 11102 m
+gs 1 -1 sc (1) col-1 sh gr
+/Times-Bold-iso ff 210.00 scf sf
+2627 10502 m
+gs 1 -1 sc (2) col-1 sh gr
+/Times-Bold-iso ff 210.00 scf sf
+3077 10127 m
+gs 1 -1 sc (2) col-1 sh gr
+/Times-Bold-iso ff 210.00 scf sf
+3527 10727 m
+gs 1 -1 sc (5) col-1 sh gr
+/Times-Bold-iso ff 210.00 scf sf
+3827 9827 m
+gs 1 -1 sc (6) col-1 sh gr
+/Times-Bold-iso ff 210.00 scf sf
+827 10277 m
+gs 1 -1 sc (1) col-1 sh gr
+/Helvetica-BoldOblique-iso ff 210.00 scf sf
+750 9150 m
+gs 1 -1 sc ([4]) col-1 sh gr
+/Helvetica-BoldOblique-iso ff 210.00 scf sf
+600 11025 m
+gs 1 -1 sc ([2]) col-1 sh gr
+/Helvetica-BoldOblique-iso ff 210.00 scf sf
+1950 8325 m
+gs 1 -1 sc ([1]) col-1 sh gr
+/Helvetica-BoldOblique-iso ff 210.00 scf sf
+3300 8925 m
+gs 1 -1 sc ([6]) col-1 sh gr
+/Helvetica-BoldOblique-iso ff 210.00 scf sf
+2325 9900 m
+gs 1 -1 sc ([5]) col-1 sh gr
+/Helvetica-BoldOblique-iso ff 210.00 scf sf
+2925 11400 m
+gs 1 -1 sc ([3]) col-1 sh gr
+/Helvetica-BoldOblique-iso ff 210.00 scf sf
+4350 10500 m
+gs 1 -1 sc ([2]) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+1353 12828 m
+gs 1 -1 sc (7 11 11) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+1353 13098 m
+gs 1 -1 sc (4 5 1 3 2 2 1) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+1353 13368 m
+gs 1 -1 sc (2 1 1 3 2 4 1) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+1353 13638 m
+gs 1 -1 sc (5 5 3 4 2 2 2 1 2) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+1353 13908 m
+gs 1 -1 sc (3 2 1 3 2 6 2 7 5) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+1353 14178 m
+gs 1 -1 sc (1 1 1 3 3 6 2) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+1353 14448 m
+gs 1 -1 sc (6 5 2 4 2 7 6) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+1353 14718 m
+gs 1 -1 sc (2 6 6 4 5) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+7728 12978 m
+gs 1 -1 sc (7 11 10 3) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+7728 13248 m
+gs 1 -1 sc (1 2 0 5 3 2) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+7728 13518 m
+gs 1 -1 sc (0 2 2 1 3 4) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+7728 14058 m
+gs 1 -1 sc (2 2 3 2 3 6 7) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+7728 14328 m
+gs 1 -1 sc (1 1 1 1 3 6) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+7728 14598 m
+gs 1 -1 sc (2 2 1 5 4 7) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+7728 14868 m
+gs 1 -1 sc (1 2 1 6 4) col-1 sh gr
+/Courier-iso ff 210.00 scf sf
+7728 13788 m
+gs 1 -1 sc (4 1 1 5 4 2 1) col-1 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+1501 7351 m
+gs 1 -1 sc (\(a\)) dup sw pop neg 0 rm  col-1 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+1801 7351 m
+gs 1 -1 sc (Unweighted Graph) col-1 sh gr
+% Polyline
+n 301 3826 m 4351 3826 l gs col-1 s gr 
+/Times-Roman-iso ff 180.00 scf sf
+600 4350 m
+gs 1 -1 sc (Graph File:) col-1 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+1052 15377 m
+gs 1 -1 sc (\(c\)) dup sw pop neg 0 rm  col-1 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+1352 15377 m
+gs 1 -1 sc (Weighted Graph) col-1 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+1352 15647 m
+gs 1 -1 sc (Weights both on vertices and edges) col-1 sh gr
+% Polyline
+n 452 11927 m 4652 11927 l gs col-1 s gr 
+/Times-Roman-iso ff 180.00 scf sf
+751 12451 m
+gs 1 -1 sc (Graph File:) col-1 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+8026 7276 m
+gs 1 -1 sc (\(b\)) dup sw pop neg 0 rm  col-1 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+8326 7276 m
+gs 1 -1 sc (Weighted Graph) col-1 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+8326 7546 m
+gs 1 -1 sc (Weights on edges) col-1 sh gr
+% Polyline
+n 6827 12077 m 10877 12077 l gs col-1 s gr 
+% Polyline
+n 6601 3827 m 10726 3827 l gs col-1 s gr 
+% Polyline
+n 6450 8100 m 11325 8100 l 11325 15900 l 6450 15900 l cp gs col0 s gr 
+% Polyline
+n 150 8100 m 5025 8100 l 5025 15900 l 150 15900 l cp gs col0 s gr 
+% Polyline
+n 150 75 m 5025 75 l 5025 7875 l 150 7875 l cp gs col0 s gr 
+% Polyline
+n 6450 75 m 11325 75 l 11325 7875 l 6450 7875 l cp gs col0 s gr 
+/Times-BoldItalic-iso ff 210.00 scf sf
+6600 11100 m
+gs 1 -1 sc ([0, 2, 2]) col0 sh gr
+/Times-BoldItalic-iso ff 210.00 scf sf
+7050 9225 m
+gs 1 -1 sc ([1, 2, 0]) col0 sh gr
+/Times-BoldItalic-iso ff 210.00 scf sf
+8175 8475 m
+gs 1 -1 sc ([1, 1, 1]) col0 sh gr
+/Times-BoldItalic-iso ff 210.00 scf sf
+9525 9075 m
+gs 1 -1 sc ([2, 2, 1]) col0 sh gr
+/Times-BoldItalic-iso ff 210.00 scf sf
+8700 10050 m
+gs 1 -1 sc ([4, 1, 1]) col0 sh gr
+/Times-BoldItalic-iso ff 210.00 scf sf
+10425 10350 m
+gs 1 -1 sc ([1, 2, 1]) col0 sh gr
+/Times-BoldItalic-iso ff 210.00 scf sf
+9225 11550 m
+gs 1 -1 sc ([2, 2, 3]) col0 sh gr
+/Times-Roman-iso ff 180.00 scf sf
+7126 12601 m
+gs 1 -1 sc (Graph File:) col-1 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+8027 15602 m
+gs 1 -1 sc (\(d\)) dup sw pop neg 0 rm  col-1 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+8327 15602 m
+gs 1 -1 sc (Multi-Constraint Graph) col-1 sh gr
+/Times-Roman-iso ff 180.00 scf sf
+6900 4351 m
+gs 1 -1 sc (Graph File:) col-1 sh gr
+$F2psEnd
+rs
+%%EndDocument
+ @endspecial 1168 4002 a Fy(Figure)18 b(8)p FL(:)25 b
+Fx(Stor)o(age)19 b(f)n(or)r(mat)f(f)n(or)g(v)n(ar)q(ious)h(type)g(of)f
+(g)o(r)o(aphs)o(.)0 4186 y FL(to)i(1,)g(indicating)f(the)h(f)o(act)h
+(that)h Ft(G)k FL(has)20 b(weights)g(on)g(the)g(edges.)100
+4296 y(In)e(addition)g(to)h(ha)n(ving)f(weights)g(on)h(the)g(edges,)f
+(weights)h(on)f(the)h(v)o(ertices)g(are)f(also)i(allo)n(wed,)e(as)h
+(illustrated)g(in)g(Figure)f(8\(c\).)24 b(In)0 4406 y(this)f(case,)h
+(the)f(v)n(alue)f(of)g Fs(fmt)j FL(is)f(equal)e(to)h(11,)g(and)f(each)g
+(line)h(of)g(the)f(graph)g(\002le)h(\002rst)h(stores)f(the)g(weight)f
+(of)g(the)h(v)o(erte)o(x,)f(and)g(then)0 4515 y(the)e(weighted)f
+(adjacenc)o(y)g(list.)100 4625 y(Finally)-5 b(,)22 b(Figure)h(8\(d\))f
+(illustrates)h(the)g(format)f(of)h(the)g(input)f(\002le)h(when)g(the)g
+(v)o(ertices)f(of)h(the)g(graph)e(contain)h(multiple)h(weights)0
+4734 y(\(3)h(in)g(this)g(e)o(xample\).)34 b(In)24 b(this)g(case,)h(the)
+f(v)n(alue)f(of)g Fs(fmt)i FL(is)g(equal)e(to)h(10)f(\(we)h(do)g(not)f
+(ha)n(v)o(e)g(weights)h(associated)g(with)g(the)g(edges\),)0
+4844 y(and)e(the)g(v)n(alue)f(of)h Fs(ncon)f FL(is)i(equal)e(to)i(3)f
+(\(since)g(we)g(ha)n(v)o(e)g(three)f(sets)i(of)f(v)o(erte)o
+(x-weights\).)28 b(Each)22 b(line)g(of)g(the)g(graph)e(\002le)j(stores)
+g(the)0 4954 y(three)d(weights)g(of)g(the)g(v)o(ertices)g(follo)n(wed)e
+(by)i(the)g(adjacenc)o(y)f(list.)0 5163 y FB(4.5.2)84
+b(Mesh)23 b(File)0 5289 y FL(The)h(primary)g(input)g(of)g(the)h(mesh)f
+(partitioning)f(programs)g(in)k Fz(M)l FG(E)-17 b Fz(T)g
+FG(I)p Fz(S)29 b FL(is)c(the)g(mesh)g(to)g(be)f(partitioned.)37
+b(This)25 b(mesh)g(is)g(stored)f(in)0 5399 y(a)f(\002le)h(in)f(the)g
+(form)f(of)h(the)g(element)g(node)f(array)-5 b(.)32 b(A)23
+b(mesh)g(with)g Ft(n)k FL(elements)c(is)h(stored)e(in)h(a)h(plain)e(te)
+o(xt)h(\002le)h(that)f(contains)f Ft(n)i FM(C)c FL(1)1908
+5649 y(16)p eop
+%%Page: 17 17
+17 16 bop 0 83 a FL(lines.)30 b(The)22 b(\002rst)g(line)g(contains)f
+(information)f(about)g(the)i(size)h(and)e(the)h(type)f(of)h(the)f
+(mesh,)h(while)g(the)g(remaining)e Ft(n)25 b FL(lines)e(contain)0
+193 y(the)d(nodes)g(that)g(mak)o(e)g(up)f(each)h(element.)100
+302 y(The)i(\002rst)h(line)f(contains)g(tw)o(o)g(inte)o(gers.)31
+b(The)22 b(\002rst)h(inte)o(ger)e(is)i(the)g(number)d(of)i(elements)g
+Ft(n)k FL(in)d(the)f(mesh.)31 b(The)22 b(second)g(inte)o(ger)0
+412 y Fs(etype)e FL(is)h(used)f(to)g(denote)f(the)h(type)f(of)h
+(elements)g(that)g(the)g(mesh)g(is)h(made)e(of)n(f.)25
+b Fs(Etype)19 b FL(can)h(either)g(tak)o(e)g(the)g(v)n(alues)f(of)h(1,)g
+(2,)g(3,)g(or)g(4,)0 521 y(indicating)f(that)h(the)g(mesh)g(consists)h
+(of)f(either)g(triangles,)f(tetrahedra,)g(he)o(xahedra)e(\(bricks\),)i
+(or)h(quadrilaterals,)e(respecti)n(v)o(ely)-5 b(.)100
+631 y(After)21 b(the)g(\002rst)h(line,)f(the)h(remaining)d
+Ft(n)25 b FL(lines)d(store)f(the)g(element)g(node)f(array)-5
+b(.)27 b(In)21 b(particular)f(for)h(element)e Ft(i)9
+b FL(,)22 b(line)e Ft(i)28 b FM(C)19 b FL(1)i(stores)0
+741 y(the)j(nodes)g(that)g(this)h(element)f(is)h(made)e(of)n(f.)37
+b(Depending)22 b(on)i Fs(etype)p FL(,)h(each)f(line)g(can)g(either)g
+(ha)n(v)o(e)g(three)f(inte)o(gers)h(\(in)g(the)g(case)h(of)0
+850 y(triangles\),)e(four)g(inte)o(gers)g(\(in)g(the)g(case)h(of)g
+(tetrahedra)e(and)h(quadrilaterals\),)f(or)h(eight)h(inte)o(gers)e
+(\(in)i(the)f(case)h(of)g(he)o(xahedra\).)32 b(In)0 960
+y(the)22 b(case)g(of)g(triangles)f(and)g(tetrahedra,)g(the)h(ordering)d
+(of)j(the)g(nodes)f(for)g(each)h(element)f(does)h(not)f(matter)-5
+b(.)30 b(Ho)n(we)n(v)o(er)m(,)20 b(in)i(the)g(case)0
+1069 y(of)f(he)o(xahedra)e(and)i(quadrilaterals,)f(the)i(nodes)e(for)h
+(each)g(element)g(should)g(be)g(ordered)f(according)f(to)j(the)f
+(numbering)e(illustrated)0 1179 y(in)h(Figure)g(9\(b\).)k(Note)c(that)g
+(the)g(node)f(numbering)f(starts)j(from)e(1.)100 1289
+y(Figure)h(9)h(illustrates)h(this)g(format)e(for)g(a)i(small)f(mesh)g
+(with)g(triangular)f(elements.)27 b(Note)21 b(that)h(the)f
+Fs(etype)g FL(\002eld)g(of)g(the)g(mesh)g(\002le)0 1398
+y(is)g(set)g(to)f(1)h(indicating)e(that)h(the)g(mesh)g(consists)h(of)f
+(triangular)e(elements.)750 2599 y @beginspecial 0 @llx
+0 @lly 469 @urx 215 @ury 2880 @rwi @setspecial
+%%BeginDocument: ./figures/meshformat.eps
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {} def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+-32.0 264.0 translate
+1 -1 scale
+
+/clp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+  bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+  4 -2 roll mul srgb} bind def
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+10 setmiterlimit
+ 0.06000 0.06000 sc
+/Times-Roman findfont 180.00 scalefont setfont
+750 2850 m
+gs 1 -1 sc (Mesh File:) col-1 show gr
+/Helvetica-Bold findfont 210.00 scalefont setfont
+1650 4350 m
+gs 1 -1 sc (\(a\) Sample Mesh File) dup stringwidth pop 2 div neg 0 rmoveto  col-1 show gr
+/Helvetica findfont 180.00 scalefont setfont
+4350 2566 m
+gs 1 -1 sc (2) col-1 show gr
+/Helvetica findfont 180.00 scalefont setfont
+5430 2700 m
+gs 1 -1 sc (3) col-1 show gr
+/Helvetica findfont 180.00 scalefont setfont
+1605 2288 m
+gs 1 -1 sc (1) col-1 show gr
+/Helvetica findfont 180.00 scalefont setfont
+1597 1268 m
+gs 1 -1 sc (6) col-1 show gr
+/Helvetica findfont 180.00 scalefont setfont
+2183 1860 m
+gs 1 -1 sc (3) col-1 show gr
+/Helvetica findfont 180.00 scalefont setfont
+2145 952 m
+gs 1 -1 sc (5) col-1 show gr
+/Helvetica findfont 180.00 scalefont setfont
+1043 930 m
+gs 1 -1 sc (4) col-1 show gr
+/Helvetica findfont 180.00 scalefont setfont
+6053 2310 m
+gs 1 -1 sc (4) col-1 show gr
+/Helvetica findfont 180.00 scalefont setfont
+8228 2385 m
+gs 1 -1 sc (4) col-1 show gr
+/Helvetica findfont 180.00 scalefont setfont
+7050 1441 m
+gs 1 -1 sc (2) col-1 show gr
+/Helvetica-Bold findfont 210.00 scalefont setfont
+6450 3375 m
+gs 1 -1 sc (\(b\) Ordering of nodes) dup stringwidth pop 2 div neg 0 rmoveto  col-1 show gr
+/Helvetica findfont 180.00 scalefont setfont
+7043 2378 m
+gs 1 -1 sc (1) col-1 show gr
+/Helvetica findfont 180.00 scalefont setfont
+8205 1425 m
+gs 1 -1 sc (3) col-1 show gr
+/Helvetica findfont 180.00 scalefont setfont
+4958 1312 m
+gs 1 -1 sc (5) col-1 show gr
+/Helvetica findfont 180.00 scalefont setfont
+4350 1650 m
+gs 1 -1 sc (6) col-1 show gr
+/Helvetica findfont 180.00 scalefont setfont
+5468 1800 m
+gs 1 -1 sc (7) col-1 show gr
+/Helvetica findfont 180.00 scalefont setfont
+6030 1379 m
+gs 1 -1 sc (8) col-1 show gr
+/Helvetica findfont 180.00 scalefont setfont
+4943 2228 m
+gs 1 -1 sc (1) col-1 show gr
+/Helvetica findfont 180.00 scalefont setfont
+1050 1875 m
+gs 1 -1 sc (2) col-1 show gr
+/Courier findfont 180.00 scalefont setfont
+1725 3900 m
+gs 1 -1 sc (5 6 3) col-1 show gr
+7.500 slw
+% Polyline
+n 1200 900 m 1200 1800 l  2100 1800 l  2100 900 l  1200 900 l  gs col-1 s gr 
+% Polyline
+n 1200 900 m 2100 1800 l  gs col-1 s gr 
+% Polyline
+n 1650 1350 m 1200 1800 l  gs col-1 s gr 
+/Courier findfont 180.00 scalefont setfont
+1725 3690 m
+gs 1 -1 sc (4 5 6) col-1 show gr
+/Courier findfont 180.00 scalefont setfont
+1725 2850 m
+gs 1 -1 sc (5 1) col-1 show gr
+/Courier findfont 180.00 scalefont setfont
+1725 3060 m
+gs 1 -1 sc (1 2 3) col-1 show gr
+/Courier findfont 180.00 scalefont setfont
+1725 3270 m
+gs 1 -1 sc (2 4 6) col-1 show gr
+/Courier findfont 180.00 scalefont setfont
+1725 3480 m
+gs 1 -1 sc (2 6 3) col-1 show gr
+% Polyline
+n 2100 900 m 1650 1350 l  gs col-1 s gr 
+% Polyline
+n 5100 1335 m 4500 1635 l  gs col-1 s gr 
+% Polyline
+n 6000 1335 m 5400 1635 l  gs col-1 s gr 
+% Polyline
+n 5100 2235 m 4500 2535 l  gs col-1 s gr 
+% Polyline
+n 6000 2235 m 5400 2535 l  gs col-1 s gr 
+% Polyline
+n 4500 1635 m 5400 1635 l  5400 2535 l  4500 2535 l  clp  gs col-1 s gr 
+% Polyline
+n 1200 1800 m 1650 2400 l  gs col-1 s gr 
+% Polyline
+n 2100 1800 m 1650 2400 l  gs col-1 s gr 
+% Polyline
+n 600 2550 m 2550 2550 l  gs col-1 s gr 
+% Polyline
+n 7200 1500 m 8100 1500 l  8100 2400 l  7200 2400 l  clp  gs col-1 s gr 
+% Polyline
+n 5100 1335 m 6000 1335 l  6000 2235 l  5100 2235 l  clp  gs col-1 s gr 
+$F2psEnd
+restore
+%%EndDocument
+ @endspecial 180 2782 a Fy(Figure)g(9)p FL(:)25 b Fx(\(a\))19
+b(The)f(\002le)h(that)f(stores)h(the)f(mesh.)23 b(\(b\))18
+b(The)g(order)q(ing)g(of)h(the)f(nodes)h(in)g(the)f(case)h(of)g(he)n
+(xahedr)o(a)f(and)g(quadr)q(ilater)o(als)o(.)0 3093 y
+Fr(4.6)100 b(Output)27 b(File)h(Formats)0 3252 y FL(The)h(output)f(of)k
+Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)33 b FL(is)e(either)e(a)h
+(partition)e(or)i(an)f(ordering)e(\002le,)33 b(depending)27
+b(on)i(whether)h Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)34
+b FL(is)c(used)g(for)f(graph/mesh)0 3362 y(partitioning)18
+b(or)i(for)g(sparse)g(matrix)f(ordering.)k(The)d(format)f(of)h(these)g
+(\002les)i(are)e(described)f(in)h(the)g(follo)n(wing)f(sections.)0
+3571 y FB(4.6.1)84 b(P)n(ar)r(tition)22 b(File)0 3697
+y FL(The)28 b(partition)g(\002le)i(of)e(a)h(graph)f(with)h
+Ft(n)j FL(v)o(ertices)d(consists)g(of)f Ft(n)33 b FL(lines)c(with)g(a)g
+(single)g(number)e(per)h(line.)51 b(The)28 b Ft(i)9 b
+FL(th)28 b(line)h(of)g(the)0 3807 y(\002le)d(contains)e(the)h
+(partition)e(number)g(that)i(the)f Ft(i)9 b FL(th)25
+b(v)o(erte)o(x)e(belongs)h(to.)39 b(P)o(artition)24 b(numbers)f(start)j
+(from)e(0)g(up)h(to)g(the)g(number)e(of)0 3916 y(partitions)c(minus)h
+(one.)0 4126 y FB(4.6.2)84 b(Or)n(dering)23 b(File)0
+4252 y FL(The)28 b(ordering)f(\002le)j(of)e(a)h(graph)f(with)h
+Ft(n)j FL(v)o(ertices)d(consists)g(of)f Ft(n)33 b FL(lines)c(with)g(a)g
+(single)g(number)e(per)h(line.)51 b(The)28 b Ft(i)9 b
+FL(th)28 b(line)h(of)g(the)0 4361 y(ordering)18 b(\002le)j(contains)e
+(the)i(ne)n(w)f(order)e(of)i(the)g Ft(i)9 b FL(th)20
+b(v)o(erte)o(x)e(of)i(the)g(graph.)k(The)c(numbering)d(in)k(the)f
+(ordering)e(\002le)j(starts)g(from)e(0.)100 4471 y(Note)g(that)g(the)g
+(ordering)d(\002le)k(stores)f(what)g(is)h(referred)d(to)i(as)h(the)f
+(the)g(in)m(v)o(erse)f(permutation)e(v)o(ector)i Fs(iperm)h
+FL(of)g(the)g(ordering.)j(Let)8 4581 y Ft(A)g FL(be)e(a)g(matrix)f(and)
+g(let)29 b Ft(A)779 4550 y Fe(0)820 4581 y FL(be)20 b(the)f(reordered)f
+(matrix.)24 b(The)19 b(in)m(v)o(erse)g(permutation)f(v)o(ector)g(maps)i
+(the)f Ft(i)9 b FL(th)19 b(ro)n(w)h(\(column\))d(of)28
+b Ft(A)22 b FL(into)0 4690 y(the)e Fs(iperm)p FM(T)o
+Ft(i)9 b FM(U)19 b FL(ro)n(w)h(\(column\))e(of)28 b Ft(A)1046
+4660 y Fe(0)1067 4690 y FL(.)1908 5649 y(17)p eop
+%%Page: 18 18
+18 17 bop 0 85 a FD(5)119 b(M)-6 b FA(E)-23 b FD(T)g
+FA(I)p FD(S)s(')-7 b(s)31 b(Librar)q(y)h(Interface)0
+261 y FL(The)17 b(v)n(arious)g(programs)f(pro)o(vided)f(in)20
+b Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)22 b FL(can)c(also)g(be)f
+(directly)g(accessed)h(from)f(a)h(C)g(or)g(F)o(ortran)e(program)g(by)h
+(using)g(the)h(stand-)0 370 y(alone)27 b(library)h Fz(M)l
+FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)p FL(.)49 b(Furthermore,)29
+b Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)30 b FL(e)o(xtends)d(the)g
+(functionality)e(pro)o(vided)g(by)k Fz(M)l FG(E)-17 b
+Fz(T)g FG(I)p Fz(S)r FL(')-5 b(s)30 b(stand-alone)25
+b(programs)0 480 y(in)h(tw)o(o)h(dif)n(ferent)d(w)o(ays.)43
+b(First,)29 b(it)d(allo)n(ws)h(the)f(user)g(to)g(alter)h(the)f(beha)n
+(vior)e(of)i(the)g(v)n(arious)f(algorithms)g(in)k Fz(M)l
+FG(E)-17 b Fz(T)g FG(I)p Fz(S)r FL(,)28 b(and)d(second)2
+590 y Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)31 b
+FL(pro)o(vides)26 b(additional)g(routines)h(that)g(can)h(be)f(used)g
+(to)h(partition)f(graphs)f(into)i(unequal-size)d(partitions)i(and)g
+(compute)0 699 y(partitionings)19 b(that)h(directly)f(minimize)h(the)g
+(total)g(communication)d(v)n(olume.)100 809 y(In)24 b(the)g(rest)g(of)g
+(this)h(section)f(we)h(describe)e(the)h(interf)o(ace)f(to)i(the)f
+(routines)f(in)k Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)27
+b FL(by)d(\002rst)h(describing)d(the)j(v)n(arious)e(data)0
+918 y(structures)e(used)h(to)g(pass)g(information)e(into)h(and)h(get)f
+(information)f(out)h(of)h(the)g(routines,)f(follo)n(wed)f(by)i(a)g
+(detailed)f(description)g(of)0 1028 y(the)f(calling)g(sequence)f(of)h
+(the)g(v)n(arious)f(routines.)0 1255 y Fr(5.1)100 b(Graph)27
+b(Data)i(Structure)0 1415 y FL(All)24 b(of)f(the)h(graph)e
+(partitioning)f(and)i(sparse)h(matrix)f(ordering)e(routines)h(in)k
+Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)27 b FL(tak)o(e)c(as)h
+(input)f(the)h(adjacenc)o(y)d(structure)i(of)0 1524 y(the)d(graph)f
+(and)h(the)g(weights)g(of)g(the)g(v)o(ertices)g(and)f(edges)h(\(if)g
+(an)o(y\).)100 1634 y(The)25 b(adjacenc)o(y)e(structure)h(of)h(the)h
+(graph)e(is)i(stored)f(using)f(the)i(compressed)d(storage)i(format)f
+(\(CSR\).)i(The)f(CSR)i(format)d(is)i(a)0 1744 y(widely)e(used)h
+(scheme)g(for)f(storing)g(sparse)h(graphs.)38 b(In)24
+b(this)i(format)e(the)g(adjacenc)o(y)g(structure)g(of)g(a)h(graph)f
+(with)h Ft(n)k FL(v)o(ertices)24 b(and)0 1853 y Ft(m)k
+FL(edges)22 b(is)h(represented)e(using)h(tw)o(o)g(arrays)g
+Fp(xadj)h FL(and)e Fp(adjncy)p FL(.)32 b(The)22 b Fp(xadj)g
+FL(array)f(is)j(of)e(size)h Ft(n)g FM(C)d FL(1)j(whereas)f(the)g
+Fp(adjncy)0 1963 y FL(array)d(is)i(of)f(size)h(2)p Ft(m)k
+FL(\(this)c(is)g(because)e(for)h(each)g(edge)f(between)h(v)o(ertices)f
+Fu(v)25 b FL(and)19 b Ft(u)25 b FL(we)c(actually)e(store)h(both)g
+Fu(.v)s(;)14 b Ft(u)t Fu(/)21 b FL(and)f Fu(.)p Ft(u)t
+Fu(;)14 b(v)s(/)p FL(\).)100 2072 y(The)21 b(adjacenc)o(y)e(structure)i
+(of)g(the)g(graph)f(is)j(stored)e(as)h(follo)n(ws.)28
+b(Assuming)21 b(that)g(v)o(erte)o(x)f(numbering)f(starts)j(from)e(0)i
+(\(C)g(style\),)0 2182 y(then)32 b(the)g(adjacenc)o(y)f(list)j(of)e(v)o
+(erte)o(x)e Ft(i)42 b FL(is)33 b(stored)f(in)h(array)e
+Fp(adjncy)h FL(starting)g(at)h(inde)o(x)e Fp(xadj[)o
+Ft(i)9 b Fp(])32 b FL(and)g(ending)f(at)i(\(b)n(ut)f(not)0
+2292 y(including\))17 b(inde)o(x)g Fp(xadj[)o Ft(i)22
+b FM(C)14 b FL(1)p Fp(])k FL(\()p Fs(i.e)o FL(.,)h Fp(adjncy[xadj[)o
+Ft(i)9 b Fp(]])17 b FL(through)g(and)h(including)f Fp(adjncy[xadj[)o
+Ft(i)j FM(C)14 b FL(1)p Fp(]-1])p FL(\).)23 b(That)0
+2401 y(is,)h(for)e(each)h(v)o(erte)o(x)d Ft(i)9 b FL(,)24
+b(its)g(adjacenc)o(y)d(list)j(is)g(stored)e(in)h(consecuti)n(v)o(e)e
+(locations)h(in)h(the)g(array)f Fp(adjncy)p FL(,)h(and)f(the)h(array)f
+Fp(xadj)h FL(is)0 2511 y(used)i(to)h(point)f(to)h(where)f(it)h(be)o
+(gins)f(and)g(where)g(it)h(ends.)41 b(Figure)25 b(10\(b\))f
+(illustrates)i(the)g(CSR)h(format)d(for)h(the)h(15-v)o(erte)o(x)d
+(graph)0 2620 y(sho)n(wn)c(in)i(Figure)e(10\(a\).)450
+3789 y @beginspecial 0 @llx 0 @lly 506 @urx 180 @ury
+3600 @rwi @setspecial
+%%BeginDocument: ./figures/csr.eps
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {} def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+-8.0 206.0 translate
+1 -1 scale
+
+/clp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+  bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+  4 -2 roll mul srgb} bind def
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+10 setmiterlimit
+ 0.06000 0.06000 sc
+/Times-Roman findfont 150.00 scalefont setfont
+4725 2850 m
+gs 1 -1 sc (3) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+4500 2850 m
+gs 1 -1 sc (12) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+4350 2850 m
+gs 1 -1 sc (8) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+4200 2850 m
+gs 1 -1 sc (6) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+4875 2850 m
+gs 1 -1 sc (7) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+5550 2850 m
+gs 1 -1 sc (8) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+5400 2850 m
+gs 1 -1 sc (4) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+5175 2850 m
+gs 1 -1 sc (13) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+5025 2850 m
+gs 1 -1 sc (9) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+4050 2850 m
+gs 1 -1 sc (2) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+2700 2850 m
+gs 1 -1 sc (9) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+2250 2850 m
+gs 1 -1 sc (4) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+2100 2850 m
+gs 1 -1 sc (2) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+1050 2850 m
+gs 1 -1 sc (5) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+2550 2850 m
+gs 1 -1 sc (3) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+3825 2850 m
+gs 1 -1 sc (11) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+3675 2850 m
+gs 1 -1 sc (7) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+3525 2850 m
+gs 1 -1 sc (5) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+3375 2850 m
+gs 1 -1 sc (1) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+2400 2850 m
+gs 1 -1 sc (8) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+5700 2850 m
+gs 1 -1 sc (14) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+8100 2850 m
+gs 1 -1 sc (9) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+7875 2850 m
+gs 1 -1 sc (14) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+7650 2850 m
+gs 1 -1 sc (12) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+7500 2850 m
+gs 1 -1 sc (8) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+8250 2850 m
+gs 1 -1 sc (13) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+600 2850 m
+gs 1 -1 sc (adjncy) dup stringwidth pop neg 0 rmoveto  col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+600 2550 m
+gs 1 -1 sc (xadj) dup stringwidth pop neg 0 rmoveto  col-1 show gr
+/Helvetica-Bold findfont 210.00 scalefont setfont
+3900 3375 m
+gs 1 -1 sc (\(b CSR format) dup stringwidth pop 2 div neg 0 rmoveto  col-1 show gr
+/Helvetica-Bold findfont 210.00 scalefont setfont
+3900 1500 m
+gs 1 -1 sc (\(a\) A sample graph) dup stringwidth pop 2 div neg 0 rmoveto  col-1 show gr
+7.500 slw
+% Polyline
+n 150 2250 m 8550 2250 l  8550 3000 l  150 3000 l  clp  gs col-1 s gr 
+/Times-Roman findfont 150.00 scalefont setfont
+7275 2850 m
+gs 1 -1 sc (13) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+5925 2850 m
+gs 1 -1 sc (5) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+3150 2850 m
+gs 1 -1 sc (10) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+3000 2850 m
+gs 1 -1 sc (6) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+2850 2850 m
+gs 1 -1 sc (0) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+6075 2850 m
+gs 1 -1 sc (11) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+7050 2850 m
+gs 1 -1 sc (11) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+6900 2850 m
+gs 1 -1 sc (7) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+6675 2850 m
+gs 1 -1 sc (12) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+6450 2850 m
+gs 1 -1 sc (10) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+6300 2850 m
+gs 1 -1 sc (6) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+1950 2850 m
+gs 1 -1 sc (7) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+4350 1125 m
+gs 1 -1 sc (14) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+4050 1125 m
+gs 1 -1 sc (13) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+3750 1125 m
+gs 1 -1 sc (12) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+3450 1125 m
+gs 1 -1 sc (11) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+3225 525 m
+gs 1 -1 sc (0) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+4425 525 m
+gs 1 -1 sc (4) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+4125 525 m
+gs 1 -1 sc (3) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+3825 525 m
+gs 1 -1 sc (2) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+3525 525 m
+gs 1 -1 sc (1) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+3150 1125 m
+gs 1 -1 sc (10) col-1 show gr
+% Polyline
+n 4200 525 m 4200 1125 l  gs col-1 s gr 
+% Polyline
+n 3900 525 m 3900 1125 l  gs col-1 s gr 
+% Polyline
+n 3600 525 m 3600 1125 l  gs col-1 s gr 
+% Polyline
+n 3300 525 m 4500 525 l  4500 1125 l  3300 1125 l  3300 525 l  gs col-1 s gr 
+% Polyline
+n 3300 825 m 4500 825 l  gs col-1 s gr 
+/Times-Roman findfont 150.00 scalefont setfont
+4425 825 m
+gs 1 -1 sc (9) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+4125 825 m
+gs 1 -1 sc (8) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+3825 825 m
+gs 1 -1 sc (7) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+3525 825 m
+gs 1 -1 sc (6) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+3225 825 m
+gs 1 -1 sc (5) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+900 2550 m
+gs 1 -1 sc (0) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+3975 2550 m
+gs 1 -1 sc (44) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+3750 2550 m
+gs 1 -1 sc (42) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+3525 2550 m
+gs 1 -1 sc (39) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+3300 2550 m
+gs 1 -1 sc (36) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+900 2850 m
+gs 1 -1 sc (1) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+1800 2850 m
+gs 1 -1 sc (3) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+1650 2850 m
+gs 1 -1 sc (1) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+1500 2850 m
+gs 1 -1 sc (6) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+1350 2850 m
+gs 1 -1 sc (2) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+1200 2850 m
+gs 1 -1 sc (0) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+3075 2550 m
+gs 1 -1 sc (33) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+1500 2550 m
+gs 1 -1 sc (11) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+1350 2550 m
+gs 1 -1 sc (8) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+1200 2550 m
+gs 1 -1 sc (5) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+1050 2550 m
+gs 1 -1 sc (2) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+1725 2550 m
+gs 1 -1 sc (13) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+2850 2550 m
+gs 1 -1 sc (31) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+2625 2550 m
+gs 1 -1 sc (28) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+2400 2550 m
+gs 1 -1 sc (24) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+2175 2550 m
+gs 1 -1 sc (20) col-1 show gr
+/Times-Roman findfont 150.00 scalefont setfont
+1950 2550 m
+gs 1 -1 sc (16) col-1 show gr
+$F2psEnd
+restore
+%%EndDocument
+ @endspecial 920 3971 a Fy(Figure)f(10)p FL(:)25 b Fx(An)20
+b(e)n(xample)e(of)g(the)h(CSR)h(f)n(or)r(mat)d(f)n(or)i(stor)q(ing)f
+(sparse)g(g)o(r)o(aphs)o(.)100 4164 y FL(The)h(weights)h(of)g(the)g(v)o
+(ertices)g(\(if)g(an)o(y\))f(are)h(stored)f(in)h(an)g(additional)f
+(array)g(called)h Fp(vwgt)p FL(.)25 b(If)20 b Fs(ncon)f
+FL(is)i(the)f(number)e(of)i(weights)0 4274 y(associated)h(with)h(each)f
+(v)o(erte)o(x,)f(the)i(array)f Fp(vwgt)g FL(contains)g
+Ft(n)h FM(\003)e Fs(ncon)h FL(elements)g(\(recall)g(that)g
+Ft(n)26 b FL(is)c(the)g(number)e(of)h(v)o(ertices\).)28
+b(The)0 4383 y(weights)e(of)h(the)e Ft(i)9 b FL(th)26
+b(v)o(erte)o(x)g(are)g(stored)g(in)h Fs(ncon)e FL(consecuti)n(v)o(e)g
+(entries)h(starting)h(at)g(location)e Fp(vwgt[)o Ft(i)31
+b FM(\003)23 b Fd(ncon)p Fp(])p FL(.)44 b(Note)27 b(that)f(if)0
+4493 y(each)d(v)o(erte)o(x)g(has)h(only)f(a)h(single)f(weight,)h(then)g
+Fp(vwgt)f FL(will)i(contain)d Ft(n)28 b FL(elements,)c(and)f
+Fp(vwgt[)o Ft(i)9 b Fp(])23 b FL(will)h(store)g(the)g(weight)f(of)h
+(the)-1 4603 y Ft(i)9 b FL(th)21 b(v)o(erte)o(x.)26 b(The)21
+b(v)o(erte)o(x-weights)d(must)j(be)g(inte)o(gers)f(greater)h(or)f
+(equal)h(to)g(zero.)27 b(If)21 b(all)h(the)f(v)o(ertices)f(of)h(the)g
+(graph)f(ha)n(v)o(e)g(the)h(same)0 4712 y(weight)f(\()p
+Fs(i.e)o FL(.,)g(the)h(graph)d(is)j(unweighted\),)d(then)i(the)g
+Fp(vwgt)g FL(can)g(be)g(set)h(to)f(NULL.)100 4822 y(The)c(weights)h(of)
+g(the)h(edges)e(\(if)h(an)o(y\))f(are)i(stored)e(in)h(an)h(additional)d
+(array)i(called)g Fp(adjwgt)p FL(.)23 b(This)17 b(array)g(contains)f(2)
+p Ft(m)22 b FL(elements,)0 4931 y(and)j(the)g(weight)g(of)g(edge)g
+Fp(adjncy[)14 b Ft(j)9 b Fp(])23 b FL(is)j(stored)f(at)h(location)e
+Fp(adjwgt[)14 b Ft(j)9 b Fp(])p FL(.)39 b(The)25 b(edge-weights)e(must)
+j(be)f(inte)o(gers)g(greater)0 5041 y(than)c(zero.)27
+b(If)21 b(all)h(the)f(edges)f(of)h(the)g(graph)f(ha)n(v)o(e)h(the)g
+(same)g(weight)g(\()p Fs(i.e)o FL(.,)h(the)f(graph)f(is)i
+(unweighted\),)c(then)j(the)g Fp(adjwgt)g FL(can)g(be)0
+5150 y(set)g(to)f(NULL.)100 5260 y(All)26 b(of)f(these)h(four)e(arrays)
+h(\()p Fs(xadj)p FL(,)g Fs(adjncy)p FL(,)h Fs(vwgt)p
+FL(,)h(and)e Fs(adjwgt)p FL(\))f(are)i(de\002ned)e(in)k
+Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)29 b FL(to)c(be)h(of)f(of)g
+(type)g Fp(idxtype)p FL(.)40 b(By)0 5370 y(def)o(ault)27
+b Fp(idxtype)g FL(is)h(set)h(to)e(be)h(equi)n(v)n(alent)e(to)i(type)f
+Fp(int)g FL(\()p Fs(i.e)p FL(.,)i(the)f(inte)o(ger)e(datatype)h(of)g
+(C\).)h(Ho)n(we)n(v)o(er)m(,)f Fp(idxtype)g FL(can)h(be)1908
+5649 y(18)p eop
+%%Page: 19 19
+19 18 bop 0 83 a FL(made)18 b(to)h(be)f(equi)n(v)n(alent)f(to)i(a)g
+Fp(short)49 b(int)19 b FL(for)f(certain)g(architectures)f(that)i(use)g
+(64-bit)f(inte)o(gers)g(by)g(def)o(ault.)24 b(The)18
+b(con)m(v)o(ersion)e(of)0 193 y Fp(idxtype)j FL(from)f
+Fp(int)i FL(to)f Fp(short)g FL(can)h(be)f(done)g(by)g(modifying)e(the)i
+(\002le)h Fp(Lib/struct.h)e FL(\(instructions)g(are)i(included)e
+(there\).)0 302 y(The)i(same)g Fp(idxtype)g FL(is)h(used)f(for)f(the)h
+(arrays)g(that)g(are)g(used)g(to)h(store)f(the)g(computed)e(partition)h
+(and)h(permutation)e(v)o(ector)-5 b(.)0 530 y Fr(5.2)100
+b(Mesh)28 b(Data)h(Structure)0 689 y FL(All)21 b(of)e(the)h(mesh)g
+(partitioning)e(and)h(mesh)h(con)m(v)o(ersion)d(routines)i(in)k
+Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)23 b FL(tak)o(e)d(as)g
+(input)g(the)g(element)f(node)g(array)g(of)h(a)g(mesh.)0
+799 y(This)e(element)f(node)g(array)g(is)i(stored)e(using)h(an)f(array)
+g(called)h Fp(elmnts)p FL(.)24 b(F)o(or)17 b(a)h(mesh)g(with)g
+Ft(n)k FL(elements)17 b(and)h Ft(k)23 b FL(nodes)17 b(per)g(element,)0
+908 y(the)k(size)i(of)e(the)g Fp(elmnts)g FL(array)g(is)h
+Ft(n)h FM(\003)c Ft(k)5 b FL(.)29 b(Note)22 b(that)f(since)h(the)f
+(supported)f(elements)h(in)j Fz(M)l FG(E)-17 b Fz(T)g
+FG(I)p Fz(S)25 b FL(are)d(only)e(triangles,)h(tetrahedra,)0
+1018 y(he)o(xahedra,)c(and)j(quadrilaterals,)e(the)j(possible)f(v)n
+(alues)f(for)h Ft(k)25 b FL(are)c(3,)f(4,)g(8,)g(and)f(4,)h(respecti)n
+(v)o(ely)-5 b(.)100 1127 y(The)21 b(element)g(node)g(array)g(of)h(the)f
+(mesh)h(is)h(stored)e(in)h Fp(elmnts)f FL(as)i(follo)n(ws.)29
+b(Assuming)22 b(that)g(the)f(element)h(numbering)d(starts)0
+1237 y(from)e(0)i(\(C)f(style\),)h(then)f(the)g Ft(k)24
+b FL(nodes)17 b(that)i(mak)o(e)f(up)f(element)g Ft(i)28
+b FL(are)18 b(stored)g(in)g(array)f Fp(elmnts)h FL(starting)g(at)h
+(inde)o(x)d Ft(i)k FM(\003)11 b Ft(k)24 b FL(and)18 b(ending)0
+1347 y(\(b)n(ut)23 b(not)h(including\))d(inde)o(x)i Fu(.)o
+Ft(i)29 b FM(C)21 b FL(1)p Fu(/)f FM(\003)i Ft(k)5 b
+FL(.)36 b(As)24 b(it)g(w)o(as)h(the)f(case)g(with)g(the)f(format)g(of)g
+(the)h(mesh)f(\002le)i(described)d(in)i(Section)f(4.5.2,)0
+1456 y(the)d(ordering)e(of)h(the)h(nodes)f(is)i(not)f(important)e(for)h
+(triangle)g(and)h(tetrahedra)e(elements.)25 b(Ho)n(we)n(v)o(er)m(,)17
+b(in)k(the)e(case)i(of)e(he)o(xahedra,)f(the)0 1566 y(nodes)h(for)h
+(each)g(element)f(must)i(be)f(ordered)e(according)g(to)j(the)f
+(numbering)d(illustrated)j(in)g(Figure)g(9\(b\).)100
+1675 y(The)h(array)g(that)h(describes)f(the)g(element)h(node)e(array)h
+(of)g(the)h(mesh)g(is)g(de\002ned)f(in)j Fz(M)l FG(E)-17
+b Fz(T)g FG(I)p Fz(S)r(lib)25 b FL(to)d(be)f(of)h(type)f
+Fp(idxtype)p FL(,)g(which)0 1785 y(by)f(def)o(ault)f(is)i(equi)n(v)n
+(alent)e(to)h Fp(int)g FL(\()p Fs(i.e)p FL(.,)g(inte)o(gers\).)0
+2012 y Fr(5.3)100 b(P)m(ar)r(titioning)27 b(Objectives)0
+2172 y FL(The)d(partitioning)e(algorithms)h(in)j Fz(M)l
+FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)27 b FL(can)d(be)g(used)g(to)g
+(compute)e(a)j(balanced)e Ft(k)5 b FL(-w)o(ay)23 b(partitioning)f(that)
+i(minimizes)g(either)0 2281 y(the)g(number)d(of)j(edges)f(that)g
+(straddle)g(partitions)g(\()p Fs(edg)o(ecut)p FL(\))f(or)h(the)h(total)
+g(communication)c(v)n(olume)j(\()p Fs(totalv)p FL(\).)34
+b(In)23 b(the)h(rest)g(of)f(this)0 2391 y(section)d(we)h(brie\003y)e
+(describe)g(these)i(tw)o(o)f(objecti)n(v)o(es)f(and)h(pro)o(vide)e
+(some)i(suggestions)f(on)h(when)g(the)o(y)f(should)g(be)h(used.)0
+2600 y FB(Minimizing)j(the)h(Edg)q(e-Cut)99 b FL(Consider)20
+b(a)i(graph)g Ft(G)30 b FM(D)25 b Fu(.)r Ft(V)8 b Fu(;)20
+b Ft(E)7 b Fu(/)p FL(,)22 b(and)f(let)29 b Ft(P)f FL(be)21
+b(a)h(v)o(ector)e(of)h(size)h FM(j)r Ft(V)13 b FM(j)21
+b FL(such)g(that)29 b Ft(P)6 b FM(T)o Ft(i)j FM(U)21
+b FL(stores)0 2710 y(the)f(number)f(of)h(the)g(partition)g(that)g(v)o
+(erte)o(x)e Ft(i)29 b FL(belongs)19 b(to.)26 b(The)20
+b Fs(edg)o(ecut)f FL(of)h(this)h(partitioning)d(is)k(de\002ned)d(as)i
+(the)f(number)f(of)h(edges)0 2819 y(that)d(straddle)f(partitions.)23
+b(That)16 b(is,)i(the)e(number)f(of)i(edges)f Fu(.v)s(;)e
+Ft(u)t Fu(/)k FL(for)e(which)23 b Ft(P)6 b FM(T)p Fu(v)s
+FM(U)24 b(6)r(D)30 b Ft(P)6 b FM(T)p Ft(u)t FM(U)p FL(.)24
+b(If)17 b(the)f(graph)g(has)g(weights)h(associated)0
+2929 y(with)j(the)h(edges,)e(then)h(the)g(edgecut)f(is)i(de\002ned)e
+(as)i(the)f(sum)h(of)e(the)i(weight)e(of)h(these)h(straddling)e(edges.)
+0 3138 y FB(Minimizing)26 b(the)h(T)-7 b(otal)28 b(Comm)n(unication)e
+(V)-7 b(olume)99 b FL(Consider)23 b(a)i(graph)f Ft(G)36
+b FM(D)30 b Fu(.)r Ft(V)8 b Fu(;)20 b Ft(E)7 b Fu(/)p
+FL(,)26 b(and)d(let)32 b Ft(P)f FL(be)25 b(a)f(v)o(ector)f(of)h(size)0
+3248 y FM(j)r Ft(V)12 b FM(j)20 b FL(such)f(that)26 b
+Ft(P)6 b FM(T)o Ft(i)j FM(U)19 b FL(stores)g(the)g(number)f(of)g(the)h
+(partition)f(that)i(v)o(erte)o(x)c Ft(i)28 b FL(belongs)18
+b(to.)25 b(Let)c Ft(V)2726 3260 y Ff(b)2786 3248 y FM(\032)k
+Ft(V)32 b FL(be)19 b(the)g(subset)g(of)g(interf)o(ace)f(\(or)0
+3357 y(boarder\))i(v)o(ertices.)32 b(That)23 b(is,)h(each)e(v)o(erte)o
+(x)g Fu(v)31 b FM(2)f Ft(V)1497 3369 y Ff(b)1557 3357
+y FL(is)24 b(connected)d(to)h(at)i(least)f(one)f(v)o(erte)o(x)f(that)i
+(belongs)f(to)h(a)g(dif)n(ferent)e(partition.)0 3467
+y(F)o(or)h(each)g(v)o(erte)o(x)e Fu(v)31 b FM(2)e Ft(V)740
+3479 y Ff(b)799 3467 y FL(let)g Ft(N)8 b(a)t(d)k(j)d
+FM(T)p Fu(v)s FM(U)22 b FL(be)g(the)g(number)e(of)i(domains)f(other)h
+(than)28 b Ft(P)6 b FM(T)p Fu(v)s FM(U)24 b FL(that)e(the)g(v)o
+(ertices)g(adjacent)f(to)i Fu(v)j FL(belong)0 3577 y(to.)f(The)20
+b Fs(totalv)g FL(of)g(this)g(partitioning)f(is)i(de\002ned)e(as:)1561
+3778 y Fs(totalv)j FM(D)1873 3699 y Fc(X)1861 3872 y
+Fg(v)s Fe(2)r Ff(V)1974 3882 y Fa(b)2023 3778 y Ft(N)8
+b(a)t(d)k(j)d FM(T)p Fu(v)s FM(U)p Fu(:)1463 b FL(\(1\))0
+4048 y(Equation)19 b(1)i(corresponds)e(to)i(the)g(total)g
+(communication)d(v)n(olume)i(incurred)f(by)h(the)h(partitioning)e
+(because)h(each)h(interf)o(ace)f(v)o(erte)o(x)0 4158
+y Fu(v)25 b FL(needs)19 b(to)i(be)f(sent)g(to)h(all)f(of)g(its)28
+b Ft(N)8 b(a)t(d)k(j)d FM(T)p Fu(v)s FM(U)19 b FL(partitions.)100
+4267 y(The)k(abo)o(v)o(e)e(model)i(can)g(be)g(e)o(xtended)e(to)j
+(instances)f(in)h(which)e(the)i(amount)e(of)h(data)g(that)g(needs)g(to)
+h(be)f(sent)h(for)e(each)h(node)g(is)0 4377 y(dif)n(ferent.)g(In)c
+(particular)m(,)f(if)i Fu(w)907 4389 y Fg(v)964 4377
+y FL(is)h(the)e(amount)f(of)h(data)h(that)f(needs)g(to)h(be)f(sent)h
+(for)f(v)o(erte)o(x)f Fu(v)s FL(,)j(then)e(Equation)e(1)j(can)f(be)h
+(re-written)0 4487 y(as:)1512 4596 y Fs(totalv)i FM(D)1824
+4517 y Fc(X)1812 4691 y Fg(v)s Fe(2)r Ff(V)1925 4701
+y Fa(b)1967 4596 y Fu(w)2028 4608 y Fg(v)2072 4596 y
+Ft(N)8 b(a)t(d)k(j)d FM(T)p Fu(v)s FM(U)p Fu(:)1414 b
+FL(\(2\))2 4835 y Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)24
+b FL(supports)19 b(this)j(weighted)d(totalv)h(model)g(by)g(using)h(an)f
+(array)g(called)g Fp(vsize)g FL(such)h(that)g(the)f(amount)f(of)i(data)
+f(that)h(needs)0 4944 y(to)h(be)f(sent)h(due)f(to)h(the)f
+Ft(i)9 b FL(th)21 b(v)o(erte)o(x)f(is)j(stored)e(in)h
+Fp(vsize[)o Ft(i)9 b Fp(])p FL(.)28 b(Note)22 b(that)f(the)h(amount)e
+(of)i(data)f(that)h(needs)f(to)h(be)g(sent)g(is)g(dif)n(ferent)0
+5054 y(from)j(the)g Fs(weight)h FL(of)f(the)h(v)o(erte)o(x.)39
+b(The)25 b(former)g(corresponds)e(to)j(communication)c(cost)k(whereas)f
+(the)h(later)g(corresponds)d(to)j(the)0 5164 y(computational)18
+b(cost.)100 5273 y(Note)j(that)h(for)f(partitioning)e(algorithms)h(to)i
+(correctly)e(minimize)h(the)h(totalv)-5 b(,)20 b(the)i(graph)e(should)h
+(re\003ect)g(the)h(true)f(information)0 5383 y(e)o(xchange)c
+(requirements)g(of)i(the)g(underlying)e(computations.)23
+b(F)o(or)18 b(instance,)h(the)h(dual)e(graph)g(of)h(a)h(\002nite)f
+(element)g(mesh)g(does)g(not)1908 5649 y(19)p eop
+%%Page: 20 20
+20 19 bop 0 83 a FL(correctly)19 b(model)g(the)h(underlying)e
+(communication,)f(whereas)j(the)g(nodal)f(graph)g(does.)0
+292 y FB(Whic)o(h)h(one)e(is)i(Better?)99 b FL(When)17
+b(partitioning)d(is)k(used)f(to)g(distrib)n(ute)f(a)h(graph)e(or)i(a)g
+(mesh)g(among)e(the)i(processors)e(of)i(a)g(parallel)0
+402 y(computer)m(,)24 b(the)i(edgecut)e(is)i(only)e(an)i(approximation)
+c(of)j(the)g(true)g(communication)e(cost)i(resulting)g(from)f(the)h
+(partitioning.)39 b(On)0 511 y(the)25 b(other)e(hand,)i(by)f
+(minimizing)f(the)h(totalv)g(we)h(can)g(directly)e(minimize)h(the)h(o)o
+(v)o(erall)e(communication)e(cost.)39 b(Despite)24 b(of)h(that,)0
+621 y(for)i(man)o(y)f(graphs)h(the)g(solutions)g(obtained)f(by)h
+(minimizing)f(the)i(edgecut)e(or)h(minimizing)f(the)i(totalv)-5
+b(,)28 b(are)g(comparable.)44 b(This)0 731 y(is)27 b(especially)g(true)
+f(for)g(graphs)f(corresponding)e(to)k(well-shaped)e(\002nite)i(element)
+f(meshes.)43 b(This)27 b(is)h(because)d(for)h(these)h(graphs,)0
+840 y(the)e(de)o(grees)f(of)g(the)h(v)n(arious)f(v)o(ertices)h(are)g
+(similar)g(and)f(the)h(objecti)n(v)o(es)f(of)h(minimizing)e(the)i
+(edgecut)f(or)g(the)h(totalv)g(beha)n(v)o(e)f(the)0 950
+y(same.)38 b(On)25 b(the)g(other)e(hand,)i(if)g(the)f(v)o(erte)o(x)f
+(de)o(grees)h(v)n(ary)f(signi\002cantly)h(\()p Fs(e)o(.g)o
+FL(.,)h(graphs)f(corresponding)d(to)k(linear)f(programming)0
+1059 y(matrices\),)19 b(then)h(by)g(minimizing)f(the)h(totalv)g(we)g
+(can)g(obtain)g(a)g(signi\002cant)g(reduction)e(in)j(the)f(total)g
+(communication)d(v)n(olume.)100 1169 y(In)j(terms)i(of)e(the)i(amount)d
+(of)i(time)g(required)f(by)g(these)i(tw)o(o)f(partitioning)e(objecti)n
+(v)o(es,)h(minimizing)g(the)h(edgecut)f(is)i(f)o(aster)f(than)0
+1279 y(minimizing)28 b(the)h(totalv)-5 b(.)52 b(F)o(or)29
+b(this)h(reason,)h(the)f(totalv)f(objecti)n(v)o(e)f(should)g(be)i(used)
+f(only)g(for)f(problems)g(in)i(which)f(it)h(actually)0
+1388 y(reduces)19 b(the)i(o)o(v)o(erall)d(communication)g(v)n(olume.)
+1908 5649 y(20)p eop
+%%Page: 21 21
+21 20 bop 0 83 a Fr(5.4)100 b(Graph)27 b(P)m(ar)r(titioning)g(Routines)
+0 240 y FB(METIS)p 258 240 25 4 v 31 w(P)n(ar)r(tGraphRecur)o(sive)20
+b FL(\(int)g(*n,)g(idxtype)f(*xadj,)g(idxtype)f(*adjnc)o(y)-5
+b(,)18 b(idxtype)h(*vwgt,)g(idxtype)g(*adjwgt,)g(int)h(*wgt\003ag,)1105
+350 y(int)h(*num\003ag,)d(int)i(*nparts,)f(int)h(*options,)f(int)h
+(*edgecut,)f(idxtype)f(*part\))0 587 y FB(Description)208
+697 y FL(It)23 b(is)i(used)e(to)h(partition)f(a)h(graph)e(into)h
+Ft(k)29 b FL(equal-size)23 b(parts)g(using)g(multile)n(v)o(el)g
+(recursi)n(v)o(e)f(bisection.)35 b(It)23 b(pro)o(vides)f(the)i(func-)
+208 806 y(tionality)c(of)i(the)f Fp(pmetis)g FL(program.)27
+b(The)21 b(objecti)n(v)o(e)f(of)i(the)f(partitioning)f(is)i(to)g
+(minimize)e(the)i(edgecut)e(\(as)i(described)e(in)208
+916 y(Section)f(5.3\).)0 1087 y FB(P)n(arameter)o(s)208
+1202 y FC(n)327 b FL(The)20 b(number)e(of)i(v)o(ertices)g(in)g(the)h
+(graph.)208 1314 y FC(xadj,)e(adjncy)581 1423 y FL(The)h(adjacenc)o(y)e
+(structure)i(of)g(the)g(graph)f(as)i(described)d(in)j(Section)f(5.1.)
+208 1535 y FC(vwgt,)f(adjwgt)581 1645 y FL(Information)f(about)h(the)h
+(weights)g(of)g(the)g(v)o(ertices)g(and)f(edges)h(as)h(described)e(in)h
+(Section)g(5.1.)208 1783 y FC(wgt\003ag)113 b FL(Used)21
+b(to)f(indicate)f(if)i(the)f(graph)f(is)i(weighted.)j
+Fs(wgt\003a)o(g)19 b FL(can)h(tak)o(e)h(the)f(follo)n(wing)e(v)n
+(alues:)581 1921 y(0)83 b(No)20 b(weights)g(\(vwgts)g(and)f(adjwgt)h
+(are)g(NULL\))581 2045 y(1)83 b(W)-7 b(eights)21 b(on)e(the)h(edges)g
+(only)g(\(vwgts)f(=)i(NULL\))581 2168 y(2)83 b(W)-7 b(eights)21
+b(on)e(the)h(v)o(ertices)g(only)g(\(adjwgt)f(=)i(NULL\))581
+2292 y(3)83 b(W)-7 b(eights)21 b(both)e(on)h(v)o(ertices)f(and)h
+(edges.)208 2430 y FC(num\003ag)82 b FL(Used)22 b(to)f(indicate)g
+(which)g(numbering)d(scheme)j(is)h(used)f(for)g(the)g(adjacenc)o(y)f
+(structure)g(of)h(the)g(graph.)27 b Fs(num\003a)o(g)581
+2540 y FL(can)20 b(tak)o(e)g(the)h(follo)n(wing)d(tw)o(o)j(v)n(alues:)
+581 2678 y(0)83 b(C-style)20 b(numbering)e(is)j(assumed)f(that)g
+(starts)h(from)e(0)581 2802 y(1)83 b(F)o(ortran-style)18
+b(numbering)g(is)j(assumed)e(that)i(starts)g(from)e(1)208
+2940 y FC(nparts)142 b FL(The)20 b(number)e(of)i(parts)g(to)h
+(partition)e(the)h(graph.)208 3078 y FC(options)114 b
+FL(This)22 b(is)g(an)f(array)f(of)h(5)h(inte)o(gers)e(that)h(is)i(used)
+e(to)g(pass)h(parameters)e(for)h(the)g(v)n(arious)f(phases)h(of)g(the)g
+(algorithm.)581 3187 y(If)j Fs(options[0]=0)e FL(then)h(def)o(ault)g(v)
+n(alues)g(are)h(used.)34 b(If)24 b Fs(options[0]=1)p
+FL(,)f(then)g(the)g(remaining)f(four)h(elements)g(of)581
+3297 y Fs(options)c FL(are)i(interpreted)d(as)j(follo)n(ws:)581
+3435 y(options[1])108 b(Determines)20 b(matching)e(type.)25
+b(Possible)20 b(v)n(alues)g(are:)1033 3559 y(1)83 b(Random)19
+b(Matching)g(\(RM\))1033 3683 y(2)83 b(Hea)n(vy-Edge)18
+b(Matching)h(\(HEM\))1033 3806 y(3)83 b(Sorted)19 b(Hea)n(vy-Edge)f
+(Matching)h(\(SHEM\))h(\(Def)o(ault\))1033 3930 y(Experiments)f(has)h
+(sho)n(wn)g(that)g(both)f(HEM)h(and)g(SHEM)g(perform)f(quite)g(well.)
+581 4054 y(options[2])108 b(Determines)20 b(the)g(algorithm)f(used)g
+(during)g(initial)i(partitioning.)h(Possible)f(v)n(alues)f(are:)1033
+4178 y(1)83 b(Re)o(gion)19 b(Gro)n(wing)g(\(Def)o(ault\))581
+4302 y(options[3])108 b(Determines)20 b(the)g(algorithm)f(used)g(for)h
+(re\002nement.)k(Possible)c(v)n(alues)g(are:)1033 4425
+y(1)83 b(Early-Exit)18 b(Boundary)h(FM)h(re\002nement)f(\(Def)o(ault\))
+581 4549 y(options[4])108 b(Used)21 b(for)e(deb)n(ugging)f(purposes.)23
+b(Al)o(w)o(ays)e(set)g(it)g(to)f(0)h(\(Def)o(ault\).)208
+4687 y FC(edgecut)100 b FL(Upon)19 b(successful)h(completion,)e(this)j
+(v)n(ariable)e(stores)i(the)f(number)e(of)i(edges)g(that)g(are)g(cut)h
+(by)e(the)i(partition.)208 4825 y FC(part)220 b FL(This)18
+b(is)h(a)f(v)o(ector)e(of)i(size)g Fs(n)g FL(that)g(upon)e(successful)h
+(completion)f(stores)i(the)g(partition)f(v)o(ector)f(of)h(the)h(graph.)
+23 b(The)581 4935 y(numbering)18 b(of)i(this)g(v)o(ector)f(starts)i
+(from)e(either)h(0)g(or)g(1,)g(depending)e(on)i(the)g(v)n(alue)g(of)f
+Fs(num\003a)o(g)p FL(.)0 5106 y FB(Note)208 5216 y FL(This)d(function)f
+(should)h(be)g(used)g(to)h(partition)f(a)g(graph)g(into)g(a)h(small)g
+(number)e(of)h(partitions)g(\(less)h(than)f(8\).)23 b(If)17
+b(a)g(lar)o(ge)e(number)208 5325 y(of)k(partitions)h(is)h(desired,)e
+(the)h Fz(METIS)p 1369 5325 V 31 w(P)m(ar)s(tGr)o(aphKw)o(a)n(y)g
+FL(should)f(be)i(used)e(instead,)h(as)h(it)g(is)g(signi\002cantly)e(f)o
+(aster)-5 b(.)1908 5649 y(21)p eop
+%%Page: 22 22
+22 21 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(P)n(ar)r(tGraphKwa)n(y)
+20 b FL(\(int)g(*n,)f(idxtype)g(*xadj,)g(idxtype)g(*adjnc)o(y)-5
+b(,)18 b(idxtype)g(*vwgt,)i(idxtype)e(*adjwgt,)h(int)i(*wgt\003ag,)925
+193 y(int)f(*num\003ag,)e(int)j(*nparts,)e(int)h(*options,)f(int)h
+(*edgecut,)e(idxtype)h(*part\))0 380 y FB(Description)208
+490 y FL(It)32 b(is)i(used)e(to)g(partition)g(a)g(graph)f(into)i
+Ft(k)k FL(equal-size)32 b(parts)g(using)g(the)h(multile)n(v)o(el)e
+Ft(k)5 b FL(-w)o(ay)32 b(partitioning)e(algorithm.)60
+b(It)208 600 y(pro)o(vides)17 b(the)j(functionality)e(of)h(the)h
+Fp(kmetis)f FL(program.)j(The)e(objecti)n(v)o(e)e(of)h(the)h
+(partitioning)e(is)i(to)g(minimize)f(the)h(edgecut)208
+709 y(\(as)g(described)f(in)h(Section)g(5.3\).)0 869
+y FB(P)n(arameter)o(s)208 973 y FC(n)327 b FL(The)20
+b(number)e(of)i(v)o(ertices)g(in)g(the)h(graph.)208 1074
+y FC(xadj,)e(adjncy)581 1183 y FL(The)h(adjacenc)o(y)e(structure)i(of)g
+(the)g(graph)f(as)i(described)d(in)j(Section)f(5.1.)208
+1284 y FC(vwgt,)f(adjwgt)581 1394 y FL(Information)f(about)h(the)h
+(weights)g(of)g(the)g(v)o(ertices)g(and)f(edges)h(as)h(described)e(in)h
+(Section)g(5.1.)208 1521 y FC(wgt\003ag)113 b FL(Used)21
+b(to)f(indicate)f(if)i(the)f(graph)f(is)i(weighted.)j
+Fs(wgt\003a)o(g)19 b FL(can)h(tak)o(e)h(the)f(follo)n(wing)e(v)n
+(alues:)581 1648 y(0)83 b(No)20 b(weights)g(\(vwgts)g(and)f(adjwgt)h
+(are)g(NULL\))581 1766 y(1)83 b(W)-7 b(eights)21 b(on)e(the)h(edges)g
+(only)g(\(vwgts)f(=)i(NULL\))581 1884 y(2)83 b(W)-7 b(eights)21
+b(on)e(the)h(v)o(ertices)g(only)g(\(adjwgt)f(=)i(NULL\))581
+2003 y(3)83 b(W)-7 b(eights)21 b(both)e(on)h(v)o(ertices)f(and)h
+(edges.)208 2129 y FC(num\003ag)82 b FL(Used)22 b(to)f(indicate)g
+(which)g(numbering)d(scheme)j(is)h(used)f(for)g(the)g(adjacenc)o(y)f
+(structure)g(of)h(the)g(graph.)27 b Fs(num\003a)o(g)581
+2239 y FL(can)20 b(tak)o(e)g(the)h(follo)n(wing)d(tw)o(o)j(v)n(alues:)
+581 2366 y(0)83 b(C-style)20 b(numbering)e(is)j(assumed)f(that)g
+(starts)h(from)e(0)581 2484 y(1)83 b(F)o(ortran-style)18
+b(numbering)g(is)j(assumed)e(that)i(starts)g(from)e(1)208
+2611 y FC(nparts)142 b FL(The)20 b(number)e(of)i(parts)g(to)h
+(partition)e(the)h(graph.)208 2738 y FC(options)114 b
+FL(This)22 b(is)g(an)f(array)f(of)h(5)h(inte)o(gers)e(that)h(is)i(used)
+e(to)g(pass)h(parameters)e(for)h(the)g(v)n(arious)f(phases)h(of)g(the)g
+(algorithm.)581 2848 y(If)j Fs(options[0]=0)e FL(then)h(def)o(ault)g(v)
+n(alues)g(are)h(used.)34 b(If)24 b Fs(options[0]=1)p
+FL(,)f(then)g(the)g(remaining)f(four)h(elements)g(of)581
+2957 y Fs(options)c FL(are)i(interpreted)d(as)j(follo)n(ws:)581
+3084 y(options[1])108 b(Determines)20 b(the)g(matching)f(type.)24
+b(Possible)d(v)n(alues)e(are:)1033 3203 y(1)83 b(Random)19
+b(Matching)g(\(RM\))1033 3321 y(2)83 b(Hea)n(vy-Edge)18
+b(Matching)h(\(HEM\))1033 3439 y(3)83 b(Sorted)19 b(Hea)n(vy-Edge)f
+(Matching)h(\(SHEM\))h(\(Def)o(ault\))1033 3557 y(Experiments)f(has)h
+(sho)n(wn)g(that)g(both)f(HEM)h(and)g(SHEM)g(perform)f(quite)g(well.)
+581 3676 y(options[2])108 b(Determines)20 b(the)g(algorithm)f(used)g
+(during)g(initial)i(partitioning.)h(Possible)f(v)n(alues)f(are:)1033
+3794 y(1)83 b(Multile)n(v)o(el)19 b(recursi)n(v)o(e)g(bisection)g
+(\(Def)o(ault\))581 3912 y(options[3])108 b(Determines)20
+b(the)g(algorithm)f(used)g(for)h(re\002nement.)k(Possible)c(v)n(alues)g
+(are:)1033 4030 y(1)83 b(Random)19 b(boundary)e(re\002nement)1033
+4149 y(2)83 b(Greedy)19 b(boundary)e(re\002nement)1033
+4267 y(3)83 b(Random)19 b(boundary)e(re\002nement)i(that)h(also)h
+(minimizes)f(the)g(connecti)n(vity)e(among)h(the)h(sub-)1158
+4377 y(domains)f(\(Def)o(ault\))581 4495 y(options[4])108
+b(Used)21 b(for)e(deb)n(ugging)f(purposes.)23 b(Al)o(w)o(ays)e(set)g
+(it)g(to)f(0)h(\(Def)o(ault\).)208 4622 y FC(edgecut)100
+b FL(Upon)19 b(successful)h(completion,)e(this)j(v)n(ariable)e(stores)i
+(the)f(number)e(of)i(edges)g(that)g(are)g(cut)h(by)e(the)i(partition.)
+208 4749 y FC(part)220 b FL(This)18 b(is)h(a)f(v)o(ector)e(of)i(size)g
+Fs(n)g FL(that)g(upon)e(successful)h(completion)f(stores)i(the)g
+(partition)f(v)o(ector)f(of)h(the)h(graph.)23 b(The)581
+4858 y(numbering)18 b(of)i(this)g(v)o(ector)f(starts)i(from)e(either)h
+(0)g(or)g(1,)g(depending)e(on)i(the)g(v)n(alue)g(of)f
+Fs(num\003a)o(g)p FL(.)0 5019 y FB(Note)208 5128 y FL(This)24
+b(function)f(should)g(be)i(used)f(to)h(partition)e(a)i(graph)e(into)h
+(a)h(lar)o(ge)f(number)e(of)j(partitions)e(\(greater)g(than)h(8\).)38
+b(If)24 b(a)h(small)208 5238 y(number)17 b(of)i(partitions)g(is)h
+(desired,)f(the)g Fz(METIS)p 1639 5238 V 31 w(P)m(ar)s(tGr)o
+(aphRecursiv)n(e)g FL(should)g(be)g(used)g(instead,)g(as)h(it)g
+(produces)e(some-)208 5347 y(what)i(better)f(partitions.)1908
+5649 y(22)p eop
+%%Page: 23 23
+23 22 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(P)n(ar)r(tGraphVKwa)n(y)
+20 b FL(\(int)g(*n,)g(idxtype)e(*xadj,)h(idxtype)g(*adjnc)o(y)-5
+b(,)18 b(idxtype)h(*vwgt,)g(idxtype)g(*vsize,)g(int)i(*wgt\003ag,)980
+193 y(int)f(*num\003ag,)f(int)h(*nparts,)f(int)h(*options,)f(int)h(*v)n
+(olume,)f(idxtype)g(*part\))0 452 y FB(Description)208
+561 y FL(It)28 b(is)h(used)f(to)h(partition)e(a)i(graph)e(into)h
+Ft(k)33 b FL(equal-size)28 b(parts)g(using)g(the)g(multile)n(v)o(el)f
+Ft(k)5 b FL(-w)o(ay)28 b(partitioning)e(algorithm.)48
+b(The)208 671 y(objecti)n(v)o(e)18 b(of)i(the)g(partitioning)f(is)i(to)
+f(minimize)g(the)g(total)g(communication)d(v)n(olume)j(\(as)g
+(described)f(in)h(Section)g(5.3\).)0 847 y FB(P)n(arameter)o(s)208
+966 y FC(n)327 b FL(The)20 b(number)e(of)i(v)o(ertices)g(in)g(the)h
+(graph.)208 1083 y FC(xadj,)e(adjncy)581 1193 y FL(The)h(adjacenc)o(y)e
+(structure)i(of)g(the)g(graph)f(as)i(described)d(in)j(Sections)f(5.1)f
+(and)h(5.3.)208 1309 y FC(vwgt,)f(vsize)581 1419 y FL(Information)h
+(about)j(the)g(weights)g(of)g(the)g(v)o(ertices)f(related)h(to)g(the)g
+(computation)e(and)i(communication)d(as)k(de-)581 1529
+y(scribed)c(in)g(Section)g(5.1.)208 1671 y FC(wgt\003ag)113
+b FL(Used)21 b(to)f(indicate)f(if)i(the)f(graph)f(is)i(weighted.)j
+Fs(wgt\003a)o(g)19 b FL(can)h(tak)o(e)h(the)f(follo)n(wing)e(v)n
+(alues:)581 1814 y(0)83 b(No)20 b(weights)g(\(vwgts)g(and)f(vsize)i
+(are)f(NULL\))581 1940 y(1)83 b(Communication)18 b(weights)i(only)f
+(\(vwgts)h(=)g(NULL\))581 2067 y(2)83 b(Computation)18
+b(weights)i(only)f(\(vsize)h(=)h(NULL\))581 2193 y(3)83
+b(Both)20 b(communication)d(and)j(computation)e(weights.)208
+2335 y FC(num\003ag)82 b FL(Used)22 b(to)f(indicate)g(which)g
+(numbering)d(scheme)j(is)h(used)f(for)g(the)g(adjacenc)o(y)f(structure)
+g(of)h(the)g(graph.)27 b Fs(num\003a)o(g)581 2445 y FL(can)20
+b(tak)o(e)g(the)h(follo)n(wing)d(tw)o(o)j(v)n(alues:)581
+2588 y(0)83 b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h
+(from)e(0)581 2714 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j
+(assumed)e(that)i(starts)g(from)e(1)208 2857 y FC(nparts)142
+b FL(The)20 b(number)e(of)i(parts)g(to)h(partition)e(the)h(graph.)208
+3000 y FC(options)114 b FL(This)22 b(is)g(an)f(array)f(of)h(5)h(inte)o
+(gers)e(that)h(is)i(used)e(to)g(pass)h(parameters)e(for)h(the)g(v)n
+(arious)f(phases)h(of)g(the)g(algorithm.)581 3109 y(If)j
+Fs(options[0]=0)e FL(then)h(def)o(ault)g(v)n(alues)g(are)h(used.)34
+b(If)24 b Fs(options[0]=1)p FL(,)f(then)g(the)g(remaining)f(four)h
+(elements)g(of)581 3219 y Fs(options)c FL(are)i(interpreted)d(as)j
+(follo)n(ws:)581 3362 y(options[1])108 b(Determines)20
+b(the)g(matching)f(type.)24 b(Possible)d(v)n(alues)e(are:)1033
+3488 y(1)83 b(Random)19 b(Matching)g(\(RM\))1033 3614
+y(2)83 b(Hea)n(vy-Edge)18 b(Matching)h(\(HEM\))1033 3740
+y(3)83 b(Sorted)19 b(Hea)n(vy-Edge)f(Matching)h(\(SHEM\))h(\(Def)o
+(ault\))1033 3866 y(Experiments)f(has)h(sho)n(wn)g(that)g(both)f(HEM)h
+(and)g(SHEM)g(perform)f(quite)g(well.)581 3993 y(options[2])108
+b(Determines)20 b(the)g(algorithm)f(used)g(during)g(initial)i
+(partitioning.)h(Possible)f(v)n(alues)f(are:)1033 4119
+y(1)83 b(Multile)n(v)o(el)19 b(recursi)n(v)o(e)g(bisection)g(\(Def)o
+(ault\))581 4245 y(options[3])108 b(Determines)20 b(the)g(algorithm)f
+(used)g(for)h(re\002nement.)k(Possible)c(v)n(alues)g(are:)1033
+4371 y(1)83 b(Random)19 b(boundary)e(re\002nement)i(\(Def)o(ault\))1033
+4497 y(3)83 b(Random)19 b(boundary)e(re\002nement)i(that)h(also)h
+(minimizes)f(the)g(connecti)n(vity)e(among)h(the)h(sub-)1158
+4607 y(domains)581 4733 y(options[4])108 b(Used)21 b(for)e(deb)n
+(ugging)f(purposes.)23 b(Al)o(w)o(ays)e(set)g(it)g(to)f(0)h(\(Def)o
+(ault\).)208 4876 y FC(v)o(olume)115 b FL(Upon)28 b(successful)h
+(completion,)g(this)g(v)n(ariable)f(stores)h(the)g(total)g
+(communication)d(v)n(olume)h(requires)h(by)h(the)581
+4986 y(partition.)208 5128 y FC(part)220 b FL(This)18
+b(is)h(a)f(v)o(ector)e(of)i(size)g Fs(n)g FL(that)g(upon)e(successful)h
+(completion)f(stores)i(the)g(partition)f(v)o(ector)f(of)h(the)h(graph.)
+23 b(The)581 5238 y(numbering)18 b(of)i(this)g(v)o(ector)f(starts)i
+(from)e(either)h(0)g(or)g(1,)g(depending)e(on)i(the)g(v)n(alue)g(of)f
+Fs(num\003a)o(g)p FL(.)1908 5649 y(23)p eop
+%%Page: 24 24
+24 23 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(mCP)n(ar)r(tGraphRecur)o
+(sive)20 b FL(\(int)g(*n,)f(int)i(*ncon,)d(idxtype)h(*xadj,)g(idxtype)g
+(*adjnc)o(y)-5 b(,)18 b(idxtype)g(*vwgt,)i(idxtype)e(*adjwgt,)1239
+193 y(int)i(*wgt\003ag,)f(int)i(*num\003ag,)d(int)i(*nparts,)f(int)i
+(*options,)d(int)j(*edgecut,)d(idxtype)h(*part\))0 447
+y FB(Description)208 557 y FL(It)g(is)h(used)f(to)h(partition)e(a)h
+(graph)f(into)h Ft(k)25 b FL(parts)19 b(such)g(that)g(multiple)g
+(balancing)e(constraints)i(are)g(satis\002ed.)25 b(It)20
+b(uses)g(the)f(multi-)208 666 y(constraint)h(multile)n(v)o(el)h
+(recursi)n(v)o(e)f(bisection)h(algorithm.)27 b(It)22
+b(pro)o(vides)e(the)h(functionality)f(of)h(the)h Fp(pmetis)f
+FL(program)e(when)208 776 y(it)g(is)g(used)g(to)f(compute)f(a)i
+(multi-constraint)e(partitioning.)22 b(The)d(objecti)n(v)o(e)e(of)h
+(the)h(partitioning)d(is)k(to)e(minimize)g(the)h(edgecut)208
+885 y(\(as)h(described)f(in)h(Section)g(5.3\).)0 1060
+y FB(P)n(arameter)o(s)208 1179 y FC(n)327 b FL(The)20
+b(number)e(of)i(v)o(ertices)g(in)g(the)h(graph.)208 1321
+y FC(ncon)202 b FL(The)20 b(number)e(of)i(constraints.)25
+b(This)20 b(should)f(be)h(greater)f(than)h(one)g(and)f(smaller)i(than)e
+(15.)208 1436 y FC(xadj,)g(adjncy)581 1546 y FL(The)h(adjacenc)o(y)e
+(structure)i(of)g(the)g(graph)f(as)i(described)d(in)j(Section)f(5.1.)
+208 1662 y FC(vwgt,)f(adjwgt)581 1771 y FL(Information)k(about)h(the)h
+(weights)g(of)g(the)h(v)o(ertices)e(and)h(edges)g(as)h(described)e(in)h
+(Section)g(5.1.)40 b(Note)25 b(that)h(the)581 1881 y(weight)20
+b(v)o(ector)f(must)h(be)g(supplied)f(and)h(it)h(should)e(be)h(of)g
+(size)h Fz(n*ncon)p FL(.)208 2023 y FC(wgt\003ag)113
+b FL(Used)21 b(to)f(indicate)f(if)i(the)f(graph)f(is)i(weighted.)j
+Fs(wgt\003a)o(g)19 b FL(can)h(tak)o(e)h(the)f(follo)n(wing)e(v)n
+(alues:)581 2164 y(0)83 b(No)20 b(weights)g(\(adjwgt)f(is)i(NULL\))581
+2290 y(1)83 b(W)-7 b(eights)21 b(on)e(the)h(edges.)208
+2432 y FC(num\003ag)82 b FL(Used)22 b(to)f(indicate)g(which)g
+(numbering)d(scheme)j(is)h(used)f(for)g(the)g(adjacenc)o(y)f(structure)
+g(of)h(the)g(graph.)27 b Fs(num\003a)o(g)581 2541 y FL(can)20
+b(tak)o(e)g(the)h(follo)n(wing)d(tw)o(o)j(v)n(alues:)581
+2683 y(0)83 b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h
+(from)e(0)581 2809 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j
+(assumed)e(that)i(starts)g(from)e(1)208 2951 y FC(nparts)142
+b FL(The)20 b(number)e(of)i(parts)g(to)h(partition)e(the)h(graph.)208
+3092 y FC(options)114 b FL(This)22 b(is)g(an)f(array)f(of)h(5)h(inte)o
+(gers)e(that)h(is)i(used)e(to)g(pass)h(parameters)e(for)h(the)g(v)n
+(arious)f(phases)h(of)g(the)g(algorithm.)581 3202 y(If)j
+Fs(options[0]=0)e FL(then)h(def)o(ault)g(v)n(alues)g(are)h(used.)34
+b(If)24 b Fs(options[0]=1)p FL(,)f(then)g(the)g(remaining)f(four)h
+(elements)g(of)581 3312 y Fs(options)c FL(are)i(interpreted)d(as)j
+(follo)n(ws:)581 3453 y(options[1])108 b(Determines)20
+b(the)g(matching)f(type.)24 b(Possible)d(v)n(alues)e(are:)1033
+3579 y(1)83 b(Random)19 b(Matching)g(\(RM\))1033 3705
+y(2)83 b(Hea)n(vy-Edge)18 b(Matching)h(\(HEM\))1033 3830
+y(3)83 b(Sorted)19 b(Hea)n(vy-Edge)f(Matching)h(\(SHEM\))h(\(Def)o
+(ault\))1033 3956 y(5)83 b(Sorted)19 b(Hea)n(vy-Edge)f(Matching)h
+(follo)n(wed)g(by)h(1-norm)e(Balanced-edge)g(\(SHEBM1N\))1033
+4082 y(6)83 b(Sorted)28 b(Hea)n(vy-Edge)f(Matching)h(follo)n(wed)g(by)h
+FM(1)p FL(-norm)e(Balanced-edge)g(\(SHEBMIN\))1158 4191
+y(\(Def)o(ault\))1033 4317 y(7)83 b(1-norm)18 b(Balanced-edge)g(follo)n
+(wed)h(by)h(Hea)n(vy-Edge)e(Matching)h(\(SBHEM1N\))1033
+4443 y(8)83 b FM(1)p FL(-norm)18 b(Balanced-edge)g(follo)n(wed)h(by)h
+(Hea)n(vy-Edge)e(Matching)h(\(SBHEMIN\))1033 4568 y(Experiments)g(has)j
+(sho)n(wn)e(that)h(for)g(simple)g(balancing)e(problems,)h(the)h
+(schemes)g(that)g(gi)n(v)o(e)f(pri-)1033 4678 y(ority)15
+b(to)h(hea)n(vy)e(edges)h(\()p Fs(e)o(.g)o FL(.,)h(SHEM,)g(SHEBM1N,)f
+(SHEBMIN\))g(perform)e(better)m(,)j(and)f(for)f(hard)1033
+4788 y(balancing)i(problems,)f(the)i(schemes)g(that)g(gi)n(v)o(e)g
+(priority)e(to)i(balanced)f(edges)h(\()p Fs(e)o(.g)n
+FL(.,)h(SBHEM1N,)1033 4897 y(SBHEMIN\))i(perform)e(better)-5
+b(.)581 5023 y(options[2])108 b(Determines)20 b(the)g(algorithm)f(used)
+g(during)g(initial)i(partitioning.)h(Possible)f(v)n(alues)f(are:)1033
+5149 y(1)83 b(Multi-constraint)18 b(Greedy)h(Graph)g(Gro)n(wing)1033
+5274 y(2)83 b(Random)19 b(\(Def)o(ault\))581 5400 y(options[3])108
+b(Determines)20 b(the)g(algorithm)f(used)g(for)h(re\002nement.)k
+(Possible)c(v)n(alues)g(are:)1908 5649 y(24)p eop
+%%Page: 25 25
+25 24 bop 1033 83 a FL(1)83 b(Early-Exit)18 b(Boundary)h(FM)h
+(re\002nement)f(\(Def)o(ault\))581 209 y(options[4])108
+b(Used)21 b(for)e(deb)n(ugging)f(purposes.)23 b(Al)o(w)o(ays)e(set)g
+(it)g(to)f(0)h(\(Def)o(ault\).)208 352 y FC(edgecut)100
+b FL(Upon)19 b(successful)h(completion,)e(this)j(v)n(ariable)e(stores)i
+(the)f(number)e(of)i(edges)g(that)g(are)g(cut)h(by)e(the)i(partition.)
+208 495 y FC(part)220 b FL(This)18 b(is)h(a)f(v)o(ector)e(of)i(size)g
+Fs(n)g FL(that)g(upon)e(successful)h(completion)f(stores)i(the)g
+(partition)f(v)o(ector)f(of)h(the)h(graph.)23 b(The)581
+604 y(numbering)18 b(of)i(this)g(v)o(ector)f(starts)i(from)e(either)h
+(0)g(or)g(1,)g(depending)e(on)i(the)g(v)n(alue)g(of)f
+Fs(num\003a)o(g)p FL(.)0 780 y FB(Note)208 890 y FL(This)d(function)f
+(should)g(be)i(used)f(to)h(partition)e(a)i(graph)e(into)h(a)h(small)g
+(number)e(of)h(partitions.)23 b(If)16 b(a)h(lar)o(ge)e(number)g(of)h
+(partitions)208 1000 y(is)24 b(desired,)g(the)g Fz(METIS)p
+957 1000 25 4 v 31 w(mCP)m(ar)s(tGr)o(aphKw)o(a)n(y)g
+FL(should)f(be)h(used)g(instead,)g(as)h(it)f(produces)f(some)n(what)g
+(better)g(partitions)208 1109 y(\(both)c(in)h(terms)g(of)g(quality)f
+(and)h(balance\).)1908 5649 y(25)p eop
+%%Page: 26 26
+26 25 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(mCP)n(ar)r(tGraphKwa)n
+(y)19 b FL(\(int)i(*n,)e(int)h(*ncon,)f(idxtype)g(*xadj,)g(idxtype)g
+(*adjnc)o(y)-5 b(,)17 b(idxtype)i(*vwgt,)g(idxtype)g(*adjwgt,)1058
+193 y(int)i(*wgt\003ag,)e(int)h(*num\003ag,)f(int)h(*nparts,)f(\003oat)
+h(*ub)o(v)o(ec,)e(int)i(*options,)f(int)h(*edgecut,)1058
+302 y(idxtype)f(*part\))0 560 y FB(Description)208 669
+y FL(It)g(is)h(used)f(to)h(partition)e(a)h(graph)f(into)h
+Ft(k)25 b FL(parts)19 b(such)g(that)g(multiple)g(balancing)e
+(constraints)i(are)g(satis\002ed.)25 b(It)20 b(uses)g(the)f(multi-)208
+779 y(constraint)i(multile)n(v)o(el)g Ft(k)5 b FL(-w)o(ay)21
+b(partitioning)f(algorithm.)29 b(It)22 b(pro)o(vides)e(the)i
+(functionality)e(of)i(the)g Fp(kmetis)f FL(program)f(when)208
+889 y(it)f(is)g(used)g(to)f(compute)f(a)i(multi-constraint)e
+(partitioning.)22 b(The)d(objecti)n(v)o(e)e(of)h(the)h(partitioning)d
+(is)k(to)e(minimize)g(the)h(edgecut)208 998 y(\(as)h(described)f(in)h
+(Section)g(5.3\).)0 1174 y FB(P)n(arameter)o(s)208 1293
+y FC(n)327 b FL(The)20 b(number)e(of)i(v)o(ertices)g(in)g(the)h(graph.)
+208 1436 y FC(ncon)202 b FL(The)20 b(number)e(of)i(constraints.)25
+b(This)20 b(should)f(be)h(greater)f(than)h(one)g(and)f(smaller)i(than)e
+(15.)208 1552 y FC(xadj,)g(adjncy)581 1662 y FL(The)h(adjacenc)o(y)e
+(structure)i(of)g(the)g(graph)f(as)i(described)d(in)j(Section)f(5.1.)
+208 1778 y FC(vwgt,)f(adjwgt)581 1887 y FL(Information)k(about)h(the)h
+(weights)g(of)g(the)h(v)o(ertices)e(and)h(edges)g(as)h(described)e(in)h
+(Section)g(5.1.)40 b(Note)25 b(that)h(the)581 1997 y(weight)20
+b(v)o(ector)f(must)h(be)g(supplied)f(and)h(it)h(should)e(be)h(of)g
+(size)h Fz(n*ncon)p FL(.)208 2140 y FC(wgt\003ag)113
+b FL(Used)21 b(to)f(indicate)f(if)i(the)f(graph)f(is)i(weighted.)j
+Fs(wgt\003a)o(g)19 b FL(can)h(tak)o(e)h(the)f(follo)n(wing)e(v)n
+(alues:)581 2282 y(0)83 b(No)20 b(weights)g(\(adjwgt)f(is)i(NULL\))581
+2408 y(1)83 b(W)-7 b(eights)21 b(on)e(the)h(edges.)208
+2551 y FC(num\003ag)82 b FL(Used)22 b(to)f(indicate)g(which)g
+(numbering)d(scheme)j(is)h(used)f(for)g(the)g(adjacenc)o(y)f(structure)
+g(of)h(the)g(graph.)27 b Fs(num\003a)o(g)581 2660 y FL(can)20
+b(tak)o(e)g(the)h(follo)n(wing)d(tw)o(o)j(v)n(alues:)581
+2803 y(0)83 b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h
+(from)e(0)581 2929 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j
+(assumed)e(that)i(starts)g(from)e(1)208 3071 y FC(nparts)142
+b FL(The)20 b(number)e(of)i(parts)g(to)h(partition)e(the)h(graph.)208
+3214 y FC(ub)o(v)o(ec)167 b FL(This)24 b(is)h(a)g(v)o(ector)e(of)g
+(size)i Fz(ncon)g FL(that)f(speci\002es)g(the)g(load)g(imbalance)f
+(tolerances)g(for)g(each)h(one)f(of)h(the)g Fz(ncon)581
+3323 y FL(constraints.)g(Each)c(tolerance)f(should)g(be)h(greater)g
+(than)f(1.0)h(\(preferably)d(greater)j(than)f(1.03\).)208
+3466 y FC(options)114 b FL(This)22 b(is)g(an)f(array)f(of)h(5)h(inte)o
+(gers)e(that)h(is)i(used)e(to)g(pass)h(parameters)e(for)h(the)g(v)n
+(arious)f(phases)h(of)g(the)g(algorithm.)581 3575 y(If)j
+Fs(options[0]=0)e FL(then)h(def)o(ault)g(v)n(alues)g(are)h(used.)34
+b(If)24 b Fs(options[0]=1)p FL(,)f(then)g(the)g(remaining)f(four)h
+(elements)g(of)581 3685 y Fs(options)c FL(are)i(interpreted)d(as)j
+(follo)n(ws:)581 3827 y(options[1])108 b(Determines)20
+b(the)g(matching)f(type.)24 b(Possible)d(v)n(alues)e(are:)1033
+3953 y(1)83 b(Random)19 b(Matching)g(\(RM\))1033 4079
+y(2)83 b(Hea)n(vy-Edge)18 b(Matching)h(\(HEM\))1033 4205
+y(3)83 b(Sorted)19 b(Hea)n(vy-Edge)f(Matching)h(\(SHEM\))h(\(Def)o
+(ault\))1033 4331 y(5)83 b(Sorted)19 b(Hea)n(vy-Edge)f(Matching)h
+(follo)n(wed)g(by)h(1-norm)e(Balanced-edge)g(\(SHEBM1N\))1033
+4458 y(6)83 b(Sorted)28 b(Hea)n(vy-Edge)f(Matching)h(follo)n(wed)g(by)h
+FM(1)p FL(-norm)e(Balanced-edge)g(\(SHEBMIN\))1158 4567
+y(\(Def)o(ault\))1033 4693 y(7)83 b(1-norm)18 b(Balanced-edge)g(follo)n
+(wed)h(by)h(Hea)n(vy-Edge)e(Matching)h(\(SBHEM1N\))1033
+4819 y(8)83 b FM(1)p FL(-norm)18 b(Balanced-edge)g(follo)n(wed)h(by)h
+(Hea)n(vy-Edge)e(Matching)h(\(SBHEMIN\))1033 4945 y(Experiments)g(has)j
+(sho)n(wn)e(that)h(for)g(simple)g(balancing)e(problems,)h(the)h
+(schemes)g(that)g(gi)n(v)o(e)f(pri-)1033 5055 y(ority)15
+b(to)h(hea)n(vy)e(edges)h(\()p Fs(e)o(.g)o FL(.,)h(SHEM,)g(SHEBM1N,)f
+(SHEBMIN\))g(perform)e(better)m(,)j(and)f(for)f(hard)1033
+5164 y(balancing)i(problems,)f(the)i(schemes)g(that)g(gi)n(v)o(e)g
+(priority)e(to)i(balanced)f(edges)h(\()p Fs(e)o(.g)n
+FL(.,)h(SBHEM1N,)1033 5274 y(SBHEMIN\))i(perform)e(better)-5
+b(.)581 5400 y(options[2])108 b(Determines)20 b(the)g(algorithm)f(used)
+g(during)g(initial)i(partitioning.)h(Possible)f(v)n(alues)f(are:)1908
+5649 y(26)p eop
+%%Page: 27 27
+27 26 bop 1033 83 a FL(1)83 b(Multile)n(v)o(el)19 b(recursi)n(v)o(e)g
+(bisection)1033 209 y(2)83 b(Relax)o(ed)19 b(Multile)n(v)o(el)h
+(recursi)n(v)o(e)e(bisection)i(\(Def)o(ault\))581 335
+y(options[3])108 b(Determines)20 b(the)g(algorithm)f(used)g(for)h
+(re\002nement.)k(Possible)c(v)n(alues)g(are:)1033 462
+y(1)83 b(Random)19 b(boundary)e(re\002nement)i(\(Def)o(ault\))581
+588 y(options[4])108 b(Used)21 b(for)e(deb)n(ugging)f(purposes.)23
+b(Al)o(w)o(ays)e(set)g(it)g(to)f(0)h(\(Def)o(ault\).)208
+731 y FC(edgecut)100 b FL(Upon)19 b(successful)h(completion,)e(this)j
+(v)n(ariable)e(stores)i(the)f(number)e(of)i(edges)g(that)g(are)g(cut)h
+(by)e(the)i(partition.)208 873 y FC(part)220 b FL(This)18
+b(is)h(a)f(v)o(ector)e(of)i(size)g Fs(n)g FL(that)g(upon)e(successful)h
+(completion)f(stores)i(the)g(partition)f(v)o(ector)f(of)h(the)h(graph.)
+23 b(The)581 983 y(numbering)18 b(of)i(this)g(v)o(ector)f(starts)i
+(from)e(either)h(0)g(or)g(1,)g(depending)e(on)i(the)g(v)n(alue)g(of)f
+Fs(num\003a)o(g)p FL(.)0 1159 y FB(Note)208 1269 y FL(This)24
+b(function)f(should)g(be)i(used)f(to)h(partition)e(a)i(graph)e(into)h
+(a)h(lar)o(ge)f(number)e(of)j(partitions)e(\(greater)g(than)h(8\).)38
+b(If)24 b(a)h(small)208 1378 y(number)f(of)i(partitions)g(is)h
+(desired,)g(the)g Fz(METIS)p 1683 1378 25 4 v 30 w(mCP)m(ar)s(tGr)o
+(aphRecursiv)n(e)g FL(should)e(be)h(used)h(instead,)g(as)g(it)g
+(produces)208 1488 y(some)n(what)19 b(better)h(partitions.)1908
+5649 y(27)p eop
+%%Page: 28 28
+28 27 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(WP)n(ar)r(tGraphRecur)o
+(sive)20 b FL(\(int)h(*n,)e(idxtype)g(*xadj,)g(idxtype)g(*adjnc)o(y)-5
+b(,)17 b(idxtype)i(*vwgt,)g(idxtype)g(*adjwgt,)g(int)i(*wgt\003ag,)1183
+193 y(int)g(*num\003ag,)d(int)i(*nparts,)f(\003oat)i(*tpwgts,)e(int)i
+(*options,)d(int)j(*edgecut,)d(idxtype)h(*part\))0 452
+y FB(Description)208 561 y FL(It)29 b(is)h(used)f(to)g(partition)f(a)i
+(graph)e(into)h Ft(k)34 b FL(parts)29 b(using)g(multile)n(v)o(el)f
+(recursi)n(v)o(e)g(bisection.)51 b(The)29 b(underlying)d(algorithm)i
+(is)208 671 y(similar)g(to)h(the)g(one)f(used)g(by)g
+Fz(METIS)p 1392 671 V 31 w(P)m(ar)s(tGr)o(aphRecursiv)n(e)p
+FL(,)i(b)n(ut)e(it)i(can)e(be)h(used)f(to)h(compute)e(a)i(partitioning)
+d(with)208 780 y(prescribed)19 b(partition)h(weights.)27
+b(F)o(or)20 b(e)o(xample,)g(it)h(can)g(be)g(used)g(to)g(compute)e(a)j
+(3-w)o(ay)e(partition)g(such)g(that)h(partition)f(1)h(has)208
+890 y(50\045)h(of)g(the)h(weight,)f(partition)g(2)h(has)f(20\045)h(of)f
+(the)h(weight,)f(and)g(partition)g(3)h(has)f(30\045)h(of)f(the)h
+(weight.)31 b(The)23 b(objecti)n(v)o(e)e(of)208 1000
+y(the)f(partitioning)e(is)j(to)f(minimize)g(the)g(edgecut)f(\(as)i
+(described)d(in)j(Section)f(5.3\).)0 1176 y FB(P)n(arameter)o(s)208
+1295 y FC(n)327 b FL(The)20 b(number)e(of)i(v)o(ertices)g(in)g(the)h
+(graph.)208 1412 y FC(xadj,)e(adjncy)581 1521 y FL(The)h(adjacenc)o(y)e
+(structure)i(of)g(the)g(graph)f(as)i(described)d(in)j(Section)f(5.1.)
+208 1638 y FC(vwgt,)f(adjwgt)581 1748 y FL(Information)f(about)h(the)h
+(weights)g(of)g(the)g(v)o(ertices)g(and)f(edges)h(as)h(described)e(in)h
+(Section)g(5.1.)208 1890 y FC(wgt\003ag)113 b FL(Used)21
+b(to)f(indicate)f(if)i(the)f(graph)f(is)i(weighted.)j
+Fs(wgt\003a)o(g)19 b FL(can)h(tak)o(e)h(the)f(follo)n(wing)e(v)n
+(alues:)581 2033 y(0)83 b(No)20 b(weights)g(\(vwgts)g(and)f(adjwgt)h
+(are)g(NULL\))581 2159 y(1)83 b(W)-7 b(eights)21 b(on)e(the)h(edges)g
+(only)g(\(vwgts)f(=)i(NULL\))581 2286 y(2)83 b(W)-7 b(eights)21
+b(on)e(the)h(v)o(ertices)g(only)g(\(adjwgt)f(=)i(NULL\))581
+2412 y(3)83 b(W)-7 b(eights)21 b(both)e(on)h(v)o(ertices)f(and)h
+(edges.)208 2555 y FC(num\003ag)82 b FL(Used)22 b(to)f(indicate)g
+(which)g(numbering)d(scheme)j(is)h(used)f(for)g(the)g(adjacenc)o(y)f
+(structure)g(of)h(the)g(graph.)27 b Fs(num\003a)o(g)581
+2664 y FL(can)20 b(tak)o(e)g(the)h(follo)n(wing)d(tw)o(o)j(v)n(alues:)
+581 2807 y(0)83 b(C-style)20 b(numbering)e(is)j(assumed)f(that)g
+(starts)h(from)e(0)581 2933 y(1)83 b(F)o(ortran-style)18
+b(numbering)g(is)j(assumed)e(that)i(starts)g(from)e(1)208
+3076 y FC(nparts)142 b FL(The)20 b(number)e(of)i(parts)g(to)h
+(partition)e(the)h(graph.)208 3219 y FC(tpwgts)137 b
+FL(This)17 b(is)g(an)f(array)f(containing)g Fs(nparts)h
+FL(\003oating)f(point)h(numbers.)22 b(F)o(or)16 b(partition)e
+Ft(i)9 b FL(,)17 b Fs(tpwgts[)o Ft(i)9 b Fs(])17 b FL(stores)g(the)f
+(fraction)581 3328 y(of)g(the)g(total)g(weight)g(that)g(should)f(be)h
+(assigned)f(to)i(it.)24 b(F)o(or)15 b(e)o(xample,)h(for)f(a)i(4-w)o(ay)
+e(partition)g(the)h(v)o(ector)f Fs(tpwgts[])581 3438
+y(=)j FM(f)p Fs(0.2)e(0.2)g(0.4)g(0.2)p FM(g)g FL(will)i(result)f(in)g
+(partitions)f(0,)h(1,)h(and)e(3)h(ha)n(ving)f(20\045)g(of)h(the)g
+(weight)g(and)f(partition)g(2)h(ha)n(ving)581 3548 y(40\045)j(of)g(the)
+g(weight.)25 b(Note)20 b(that)g(the)g(numbers)f(in)h
+Fs(tpwgts)h FL(should)e(add)h(up)g(to)g(1.0.)208 3690
+y FC(options)114 b FL(This)22 b(is)g(an)f(array)f(of)h(5)h(inte)o(gers)
+e(that)h(is)i(used)e(to)g(pass)h(parameters)e(for)h(the)g(v)n(arious)f
+(phases)h(of)g(the)g(algorithm.)581 3800 y(If)j Fs(options[0]=0)e
+FL(then)h(def)o(ault)g(v)n(alues)g(are)h(used.)34 b(If)24
+b Fs(options[0]=1)p FL(,)f(then)g(the)g(remaining)f(four)h(elements)g
+(of)581 3910 y Fs(options)c FL(are)i(interpreted)d(as)j(follo)n(ws:)581
+4052 y(options[1])108 b(Determines)20 b(the)g(matching)f(type.)24
+b(Possible)d(v)n(alues)e(are:)1033 4179 y(1)83 b(Random)19
+b(Matching)g(\(RM\))1033 4305 y(2)83 b(Hea)n(vy-Edge)18
+b(Matching)h(\(HEM\))1033 4431 y(3)83 b(Sorted)19 b(Hea)n(vy-Edge)f
+(Matching)h(\(SHEM\))h(\(Def)o(ault\))1033 4557 y(Experiments)f(has)h
+(sho)n(wn)g(that)g(both)f(HEM)h(and)g(SHEM)g(perform)f(quite)g(well.)
+581 4683 y(options[2])108 b(Determines)20 b(the)g(algorithm)f(used)g
+(during)g(initial)i(partitioning.)h(Possible)f(v)n(alues)f(are:)1033
+4810 y(1)83 b(Re)o(gion)19 b(Gro)n(wing)g(\(Def)o(ault\))581
+4936 y(options[3])108 b(Determines)20 b(the)g(algorithm)f(used)g(for)h
+(re\002nement.)k(Possible)c(v)n(alues)g(are:)1033 5062
+y(1)83 b(Early-Exit)18 b(Boundary)h(FM)h(re\002nement)f(\(Def)o(ault\))
+581 5188 y(options[4])108 b(Used)21 b(for)e(deb)n(ugging)f(purposes.)23
+b(Al)o(w)o(ays)e(set)g(it)g(to)f(0)h(\(Def)o(ault\).)208
+5331 y FC(edgecut)100 b FL(Upon)19 b(successful)h(completion,)e(this)j
+(v)n(ariable)e(stores)i(the)f(number)e(of)i(edges)g(that)g(are)g(cut)h
+(by)e(the)i(partition.)1908 5649 y(28)p eop
+%%Page: 29 29
+29 28 bop 208 83 a FC(part)220 b FL(This)18 b(is)h(a)f(v)o(ector)e(of)i
+(size)g Fs(n)g FL(that)g(upon)e(successful)h(completion)f(stores)i(the)
+g(partition)f(v)o(ector)f(of)h(the)h(graph.)23 b(The)581
+193 y(numbering)18 b(of)i(this)g(v)o(ector)f(starts)i(from)e(either)h
+(0)g(or)g(1,)g(depending)e(on)i(the)g(v)n(alue)g(of)f
+Fs(num\003a)o(g)p FL(.)0 369 y FB(Note)208 478 y FL(This)d(function)f
+(should)h(be)g(used)g(to)h(partition)f(a)g(graph)g(into)g(a)h(small)g
+(number)e(of)h(partitions)g(\(less)h(than)f(8\).)23 b(If)17
+b(a)g(lar)o(ge)e(number)208 588 y(of)k(partitions)h(is)h(desired,)e
+(the)h Fz(METIS)p 1369 588 25 4 v 31 w(WP)m(ar)s(tGr)o(aphKw)o(a)n(y)h
+FL(should)e(be)h(used)g(instead,)g(as)g(it)h(is)h(signi\002cantly)d(f)o
+(aster)-5 b(.)1908 5649 y(29)p eop
+%%Page: 30 30
+30 29 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(WP)n(ar)r(tGraphKwa)n(y)
+20 b FL(\(int)g(*n,)g(idxtype)e(*xadj,)h(idxtype)g(*adjnc)o(y)-5
+b(,)18 b(idxtype)h(*vwgt,)g(idxtype)g(*adjwgt,)g(int)h(*wgt\003ag,)1003
+193 y(int)g(*num\003ag,)f(int)h(*nparts,)f(\003oat)h(*tpwgts,)g(int)g
+(*options,)f(int)h(*edgecut,)e(idxtype)h(*part\))0 444
+y FB(Description)208 554 y FL(It)29 b(is)h(used)f(to)g(partition)f(a)i
+(graph)e(into)h Ft(k)34 b FL(parts)29 b(using)g(multile)n(v)o(el)f
+(recursi)n(v)o(e)g(bisection.)51 b(The)29 b(underlying)d(algorithm)i
+(is)208 663 y(similar)16 b(to)h(the)f(one)g(used)g(by)h
+Fz(METIS)p 1320 663 V 30 w(P)m(ar)s(tGr)o(aphKw)o(a)n(y)p
+FL(,)g(b)n(ut)g(it)g(can)f(be)g(used)h(to)f(compute)f(a)i(partitioning)
+e(with)h(prescribed)208 773 y(partition)24 b(weights.)42
+b(F)o(or)25 b(e)o(xample,)h(it)g(can)g(be)g(used)f(to)h(compute)e(a)j
+(3-w)o(ay)e(partition)f(such)i(that)g(partition)e(1)i(has)g(50\045)g
+(of)208 883 y(the)j(weight,)h(partition)e(2)h(has)g(20\045)g(of)g(the)f
+(weight,)j(and)d(partition)g(3)h(has)g(30\045)g(of)g(the)g(weight.)51
+b(The)28 b(objecti)n(v)o(e)g(of)h(the)208 992 y(partitioning)18
+b(is)j(to)f(minimize)g(the)g(edgecut)f(\(as)h(described)f(in)i(Section)
+e(5.3\).)0 1167 y FB(P)n(arameter)o(s)208 1284 y FC(n)327
+b FL(The)20 b(number)e(of)i(v)o(ertices)g(in)g(the)h(graph.)208
+1399 y FC(xadj,)e(adjncy)581 1509 y FL(The)h(adjacenc)o(y)e(structure)i
+(of)g(the)g(graph)f(as)i(described)d(in)j(Section)f(5.1.)208
+1624 y FC(vwgt,)f(adjwgt)581 1734 y FL(Information)f(about)h(the)h
+(weights)g(of)g(the)g(v)o(ertices)g(and)f(edges)h(as)h(described)e(in)h
+(Section)g(5.1.)208 1875 y FC(wgt\003ag)113 b FL(Used)21
+b(to)f(indicate)f(if)i(the)f(graph)f(is)i(weighted.)j
+Fs(wgt\003a)o(g)19 b FL(can)h(tak)o(e)h(the)f(follo)n(wing)e(v)n
+(alues:)581 2016 y(0)83 b(No)20 b(weights)g(\(vwgts)g(and)f(adjwgt)h
+(are)g(NULL\))581 2141 y(1)83 b(W)-7 b(eights)21 b(on)e(the)h(edges)g
+(only)g(\(vwgts)f(=)i(NULL\))581 2267 y(2)83 b(W)-7 b(eights)21
+b(on)e(the)h(v)o(ertices)g(only)g(\(adjwgt)f(=)i(NULL\))581
+2392 y(3)83 b(W)-7 b(eights)21 b(both)e(on)h(v)o(ertices)f(and)h
+(edges.)208 2533 y FC(num\003ag)82 b FL(Used)22 b(to)f(indicate)g
+(which)g(numbering)d(scheme)j(is)h(used)f(for)g(the)g(adjacenc)o(y)f
+(structure)g(of)h(the)g(graph.)27 b Fs(num\003a)o(g)581
+2643 y FL(can)20 b(tak)o(e)g(the)h(follo)n(wing)d(tw)o(o)j(v)n(alues:)
+581 2784 y(0)83 b(C-style)20 b(numbering)e(is)j(assumed)f(that)g
+(starts)h(from)e(0)581 2909 y(1)83 b(F)o(ortran-style)18
+b(numbering)g(is)j(assumed)e(that)i(starts)g(from)e(1)208
+3051 y FC(nparts)142 b FL(The)20 b(number)e(of)i(parts)g(to)h
+(partition)e(the)h(graph.)208 3192 y FC(tpwgts)137 b
+FL(This)17 b(is)g(an)f(array)f(containing)g Fs(nparts)h
+FL(\003oating)f(point)h(numbers.)22 b(F)o(or)16 b(partition)e
+Ft(i)9 b FL(,)17 b Fs(tpwgts[)o Ft(i)9 b Fs(])17 b FL(stores)g(the)f
+(fraction)581 3301 y(of)g(the)g(total)g(weight)g(that)g(should)f(be)h
+(assigned)f(to)i(it.)24 b(F)o(or)15 b(e)o(xample,)h(for)f(a)i(4-w)o(ay)
+e(partition)g(the)h(v)o(ector)f Fs(tpwgts[])581 3411
+y(=)j FM(f)p Fs(0.2)e(0.2)g(0.4)g(0.2)p FM(g)g FL(will)i(result)f(in)g
+(partitions)f(0,)h(1,)h(and)e(3)h(ha)n(ving)f(20\045)g(of)h(the)g
+(weight)g(and)f(partition)g(2)h(ha)n(ving)581 3520 y(40\045)j(of)g(the)
+g(weight.)25 b(Note)20 b(that)g(the)g(numbers)f(in)h
+Fs(tpwgts)h FL(should)e(add)h(up)g(to)g(1.0.)208 3662
+y FC(options)114 b FL(This)22 b(is)g(an)f(array)f(of)h(5)h(inte)o(gers)
+e(that)h(is)i(used)e(to)g(pass)h(parameters)e(for)h(the)g(v)n(arious)f
+(phases)h(of)g(the)g(algorithm.)581 3771 y(If)j Fs(options[0]=0)e
+FL(then)h(def)o(ault)g(v)n(alues)g(are)h(used.)34 b(If)24
+b Fs(options[0]=1)p FL(,)f(then)g(the)g(remaining)f(four)h(elements)g
+(of)581 3881 y Fs(options)c FL(are)i(interpreted)d(as)j(follo)n(ws:)581
+4022 y(options[1])108 b(Determines)20 b(the)g(matching)f(type.)24
+b(Possible)d(v)n(alues)e(are:)1033 4147 y(1)83 b(Random)19
+b(Matching)g(\(RM\))1033 4273 y(2)83 b(Hea)n(vy-Edge)18
+b(Matching)h(\(HEM\))1033 4398 y(3)83 b(Sorted)19 b(Hea)n(vy-Edge)f
+(Matching)h(\(SHEM\))h(\(Def)o(ault\))1033 4523 y(Experiments)f(has)h
+(sho)n(wn)g(that)g(both)f(HEM)h(and)g(SHEM)g(perform)f(quite)g(well.)
+581 4649 y(options[2])108 b(Determines)20 b(the)g(algorithm)f(used)g
+(during)g(initial)i(partitioning.)h(Possible)f(v)n(alues)f(are:)1033
+4774 y(1)83 b(Multile)n(v)o(el)19 b(recursi)n(v)o(e)g(bisection)g
+(\(Def)o(ault\))581 4900 y(options[3])108 b(Determines)20
+b(the)g(algorithm)f(used)g(for)h(re\002nement.)k(Possible)c(v)n(alues)g
+(are:)1033 5025 y(1)83 b(Random)19 b(boundary)e(re\002nement)1033
+5150 y(2)83 b(Greedy)19 b(boundary)e(re\002nement)1033
+5276 y(3)83 b(Random)19 b(boundary)e(re\002nement)i(that)h(also)h
+(minimizes)f(the)g(connecti)n(vity)e(among)h(the)h(sub-)1158
+5385 y(domains)f(\(Def)o(ault\))1908 5649 y(30)p eop
+%%Page: 31 31
+31 30 bop 581 83 a FL(options[4])108 b(Used)21 b(for)e(deb)n(ugging)f
+(purposes.)23 b(Al)o(w)o(ays)e(set)g(it)g(to)f(0)h(\(Def)o(ault\).)208
+226 y FC(edgecut)100 b FL(Upon)19 b(successful)h(completion,)e(this)j
+(v)n(ariable)e(stores)i(the)f(number)e(of)i(edges)g(that)g(are)g(cut)h
+(by)e(the)i(partition.)208 369 y FC(part)220 b FL(This)18
+b(is)h(a)f(v)o(ector)e(of)i(size)g Fs(n)g FL(that)g(upon)e(successful)h
+(completion)f(stores)i(the)g(partition)f(v)o(ector)f(of)h(the)h(graph.)
+23 b(The)581 478 y(numbering)18 b(of)i(this)g(v)o(ector)f(starts)i
+(from)e(either)h(0)g(or)g(1,)g(depending)e(on)i(the)g(v)n(alue)g(of)f
+Fs(num\003a)o(g)p FL(.)0 654 y FB(Note)208 764 y FL(This)24
+b(function)f(should)g(be)i(used)f(to)h(partition)e(a)i(graph)e(into)h
+(a)h(lar)o(ge)f(number)e(of)j(partitions)e(\(greater)g(than)h(8\).)38
+b(If)24 b(a)h(small)208 873 y(number)j(of)i(partitions)f(is)i(desired,)
+h(the)e Fz(METIS)p 1706 873 25 4 v 31 w(WP)m(ar)s(tGr)o(aphRecursiv)n
+(e)g FL(should)f(be)h(used)g(instead,)i(as)f(it)g(produces)208
+983 y(some)n(what)19 b(better)h(partitions.)1908 5649
+y(31)p eop
+%%Page: 32 32
+32 31 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(WP)n(ar)r(tGraphVKwa)n
+(y)20 b FL(\(int)h(*n,)e(idxtype)g(*xadj,)g(idxtype)g(*adjnc)o(y)-5
+b(,)17 b(idxtype)i(*vwgt,)g(idxtype)g(*vsize,)h(int)g(*wgt\003ag,)1058
+193 y(int)h(*num\003ag,)d(int)i(*nparts,)f(\003oat)i(*tpwgts,)e(int)i
+(*options,)d(int)j(*v)n(olume,)d(idxtype)h(*part\))0
+450 y FB(Description)208 560 y FL(It)29 b(is)h(used)f(to)g(partition)f
+(a)i(graph)e(into)h Ft(k)34 b FL(parts)29 b(using)g(multile)n(v)o(el)f
+(recursi)n(v)o(e)g(bisection.)51 b(The)29 b(underlying)d(algorithm)i
+(is)208 669 y(similar)16 b(to)h(the)f(one)g(used)g(by)h
+Fz(METIS)p 1320 669 V 30 w(P)m(ar)s(tGr)o(aphKw)o(a)n(y)p
+FL(,)g(b)n(ut)g(it)g(can)f(be)g(used)h(to)f(compute)f(a)i(partitioning)
+e(with)h(prescribed)208 779 y(partition)24 b(weights.)42
+b(F)o(or)25 b(e)o(xample,)h(it)g(can)g(be)g(used)f(to)h(compute)e(a)j
+(3-w)o(ay)e(partition)f(such)i(that)g(partition)e(1)i(has)g(50\045)g
+(of)208 888 y(the)j(weight,)h(partition)e(2)h(has)g(20\045)g(of)g(the)f
+(weight,)j(and)d(partition)g(3)h(has)g(30\045)g(of)g(the)g(weight.)51
+b(The)28 b(objecti)n(v)o(e)g(of)h(the)208 998 y(partitioning)18
+b(is)j(to)f(minimize)g(the)g(total)g(communication)e(v)n(olume)h(\(as)h
+(described)f(in)h(Section)g(5.3\).)0 1174 y FB(P)n(arameter)o(s)208
+1293 y FC(n)327 b FL(The)20 b(number)e(of)i(v)o(ertices)g(in)g(the)h
+(graph.)208 1409 y FC(xadj,)e(adjncy)581 1519 y FL(The)h(adjacenc)o(y)e
+(structure)i(of)g(the)g(graph)f(as)i(described)d(in)j(Sections)f(5.1)f
+(and)h(5.3.)208 1635 y FC(vwgt,)f(vsize)581 1745 y FL(Information)h
+(about)j(the)g(weights)g(of)g(the)g(v)o(ertices)f(related)h(to)g(the)g
+(computation)e(and)i(communication)d(as)k(de-)581 1854
+y(scribed)c(in)g(Section)g(5.1.)208 1997 y FC(wgt\003ag)113
+b FL(Used)21 b(to)f(indicate)f(if)i(the)f(graph)f(is)i(weighted.)j
+Fs(wgt\003a)o(g)19 b FL(can)h(tak)o(e)h(the)f(follo)n(wing)e(v)n
+(alues:)581 2139 y(0)83 b(No)20 b(weights)g(\(vwgts)g(and)f(vsize)i
+(are)f(NULL\))581 2265 y(1)83 b(Communication)18 b(weights)i(only)f
+(\(vwgts)h(=)g(NULL\))581 2391 y(2)83 b(Computation)18
+b(weights)i(only)f(\(vsize)h(=)h(NULL\))581 2517 y(3)83
+b(Both)20 b(communication)d(and)j(computation)e(weights.)208
+2660 y FC(num\003ag)82 b FL(Used)22 b(to)f(indicate)g(which)g
+(numbering)d(scheme)j(is)h(used)f(for)g(the)g(adjacenc)o(y)f(structure)
+g(of)h(the)g(graph.)27 b Fs(num\003a)o(g)581 2769 y FL(can)20
+b(tak)o(e)g(the)h(follo)n(wing)d(tw)o(o)j(v)n(alues:)581
+2912 y(0)83 b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h
+(from)e(0)581 3038 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j
+(assumed)e(that)i(starts)g(from)e(1)208 3180 y FC(nparts)142
+b FL(The)20 b(number)e(of)i(parts)g(to)h(partition)e(the)h(graph.)208
+3322 y FC(tpwgts)137 b FL(This)17 b(is)g(an)f(array)f(containing)g
+Fs(nparts)h FL(\003oating)f(point)h(numbers.)22 b(F)o(or)16
+b(partition)e Ft(i)9 b FL(,)17 b Fs(tpwgts[)o Ft(i)9
+b Fs(])17 b FL(stores)g(the)f(fraction)581 3432 y(of)g(the)g(total)g
+(weight)g(that)g(should)f(be)h(assigned)f(to)i(it.)24
+b(F)o(or)15 b(e)o(xample,)h(for)f(a)i(4-w)o(ay)e(partition)g(the)h(v)o
+(ector)f Fs(tpwgts[])581 3542 y(=)j FM(f)p Fs(0.2)e(0.2)g(0.4)g(0.2)p
+FM(g)g FL(will)i(result)f(in)g(partitions)f(0,)h(1,)h(and)e(3)h(ha)n
+(ving)f(20\045)g(of)h(the)g(weight)g(and)f(partition)g(2)h(ha)n(ving)
+581 3651 y(40\045)j(of)g(the)g(weight.)25 b(Note)20 b(that)g(the)g
+(numbers)f(in)h Fs(tpwgts)h FL(should)e(add)h(up)g(to)g(1.0.)208
+3794 y FC(options)114 b FL(This)22 b(is)g(an)f(array)f(of)h(5)h(inte)o
+(gers)e(that)h(is)i(used)e(to)g(pass)h(parameters)e(for)h(the)g(v)n
+(arious)f(phases)h(of)g(the)g(algorithm.)581 3903 y(If)j
+Fs(options[0]=0)e FL(then)h(def)o(ault)g(v)n(alues)g(are)h(used.)34
+b(If)24 b Fs(options[0]=1)p FL(,)f(then)g(the)g(remaining)f(four)h
+(elements)g(of)581 4013 y Fs(options)c FL(are)i(interpreted)d(as)j
+(follo)n(ws:)581 4155 y(options[1])108 b(Determines)20
+b(the)g(matching)f(type.)24 b(Possible)d(v)n(alues)e(are:)1033
+4281 y(1)83 b(Random)19 b(Matching)g(\(RM\))1033 4407
+y(2)83 b(Hea)n(vy-Edge)18 b(Matching)h(\(HEM\))1033 4533
+y(3)83 b(Sorted)19 b(Hea)n(vy-Edge)f(Matching)h(\(SHEM\))h(\(Def)o
+(ault\))1033 4659 y(Experiments)f(has)h(sho)n(wn)g(that)g(both)f(HEM)h
+(and)g(SHEM)g(perform)f(quite)g(well.)581 4785 y(options[2])108
+b(Determines)20 b(the)g(algorithm)f(used)g(during)g(initial)i
+(partitioning.)h(Possible)f(v)n(alues)f(are:)1033 4911
+y(1)83 b(Multile)n(v)o(el)19 b(recursi)n(v)o(e)g(bisection)g(\(Def)o
+(ault\))581 5037 y(options[3])108 b(Determines)20 b(the)g(algorithm)f
+(used)g(for)h(re\002nement.)k(Possible)c(v)n(alues)g(are:)1033
+5163 y(1)83 b(Random)19 b(boundary)e(re\002nement)i(\(Def)o(ault\))1033
+5289 y(3)83 b(Random)19 b(boundary)e(re\002nement)i(that)h(also)h
+(minimizes)f(the)g(connecti)n(vity)e(among)h(the)h(sub-)1158
+5399 y(domains)1908 5649 y(32)p eop
+%%Page: 33 33
+33 32 bop 581 83 a FL(options[4])108 b(Used)21 b(for)e(deb)n(ugging)f
+(purposes.)23 b(Al)o(w)o(ays)e(set)g(it)g(to)f(0)h(\(Def)o(ault\).)208
+226 y FC(v)o(olume)115 b FL(Upon)27 b(successful)h(completion,)g(this)h
+(v)n(ariable)e(stores)h(the)g(total)g(communication)e(v)n(olume)h
+(required)f(by)i(the)581 335 y(partition.)208 478 y FC(part)220
+b FL(This)18 b(is)h(a)f(v)o(ector)e(of)i(size)g Fs(n)g
+FL(that)g(upon)e(successful)h(completion)f(stores)i(the)g(partition)f
+(v)o(ector)f(of)h(the)h(graph.)23 b(The)581 588 y(numbering)18
+b(of)i(this)g(v)o(ector)f(starts)i(from)e(either)h(0)g(or)g(1,)g
+(depending)e(on)i(the)g(v)n(alue)g(of)f Fs(num\003a)o(g)p
+FL(.)1908 5649 y(33)p eop
+%%Page: 34 34
+34 33 bop 0 83 a Fr(5.5)100 b(Mesh)28 b(P)m(ar)r(titioning)g(Routines)0
+242 y FB(METIS)p 258 242 25 4 v 31 w(P)n(ar)r(tMeshNodal)20
+b FL(\(int)g(*ne,)f(int)i(*nn,)e(idxtype)g(*elmnts,)g(int)h(*etype,)f
+(int)i(*num\003ag,)d(int)i(*nparts,)f(int)i(*edgecut,)908
+352 y(idxtype)e(*epart,)g(idxtype)f(*npart\))0 611 y
+FB(Description)208 721 y FL(This)f(function)f(is)j(used)e(to)h
+(partition)e(a)i(mesh)f(into)h Ft(k)23 b FL(equal-size)16
+b(parts.)24 b(It)18 b(pro)o(vides)e(the)h(functionality)f(of)h(the)h
+Fp(partnmesh)208 830 y FL(program.)0 1006 y FB(P)n(arameter)o(s)208
+1126 y FC(ne)290 b FL(The)20 b(number)e(of)i(elements)g(in)h(the)f
+(mesh.)208 1269 y FC(nn)281 b FL(The)20 b(number)e(of)i(nodes)g(in)g
+(the)g(mesh.)208 1411 y FC(elmnts)138 b FL(The)20 b(element)g(node)f
+(array)g(storing)g(the)i(mesh)f(as)h(described)d(in)j(Section)f(5.2.)
+208 1554 y FC(etype)183 b FL(Indicates)20 b(the)g(type)g(of)f(the)i
+(elements)f(in)g(the)g(mesh.)25 b Fs(etype)20 b FL(can)g(tak)o(e)g(the)
+g(follo)n(wing)f(v)n(alues:)581 1697 y(1)83 b(The)20
+b(elements)f(are)i(triangles.)581 1823 y(2)83 b(The)20
+b(elements)f(are)i(tetrahedra.)581 1949 y(3)83 b(The)20
+b(elements)f(are)i(he)o(xahedra)c(\(bricks\).)581 2076
+y(4)83 b(The)20 b(elements)f(are)i(quadrilaterals.)208
+2218 y FC(num\003ag)82 b FL(Used)22 b(to)h(indicate)e(which)h
+(numbering)d(scheme)j(is)h(used)f(for)g(the)g(element)f(node)g(array)-5
+b(.)30 b Fs(num\003a)o(g)20 b FL(can)i(tak)o(e)h(the)581
+2328 y(follo)n(wing)c(tw)o(o)h(v)n(alues:)581 2471 y(0)83
+b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h(from)e(0)581
+2597 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j(assumed)e(that)i
+(starts)g(from)e(1)208 2740 y FC(nparts)142 b FL(The)20
+b(number)e(of)i(parts)g(to)h(partition)e(the)h(mesh.)208
+2883 y FC(edgecut)100 b FL(Upon)20 b(successful)h(completion,)f(this)i
+(v)n(ariable)e(stores)h(the)g(number)f(of)h(edges)g(that)g(are)g(cut)g
+(by)g(the)g(partition)f(in)581 2992 y(the)g(nodal)g(graph.)208
+3135 y FC(epart)183 b FL(This)18 b(is)h(a)g(v)o(ector)d(of)i(size)h
+Fs(ne)e FL(that)h(upon)f(successful)h(completion)e(stores)i(the)g
+(partition)f(v)o(ector)g(for)g(the)h(elements)581 3245
+y(of)31 b(the)f(mesh.)57 b(The)30 b(numbering)e(of)j(this)g(v)o(ector)e
+(starts)j(from)e(either)g(0)h(or)f(1,)k(depending)28
+b(on)i(the)h(v)n(alue)f(of)581 3354 y Fs(num\003a)o(g)p
+FL(.)208 3497 y FC(npart)174 b FL(This)19 b(is)g(a)g(v)o(ector)e(of)h
+(size)i Fs(nn)e FL(that)g(upon)f(successful)h(completion)f(stores)i
+(the)f(partition)g(v)o(ector)f(for)h(the)g(nodes)g(of)581
+3606 y(the)i(mesh.)25 b(The)19 b(numbering)f(of)h(this)i(v)o(ector)d
+(starts)j(from)e(either)g(0)h(or)g(1,)g(depending)d(on)j(the)g(v)n
+(alue)f(of)h Fs(num\003a)o(g)p FL(.)0 3782 y FB(Note)208
+3892 y FL(This)g(function)f(con)m(v)o(erts)g(the)h(mesh)h(into)f(a)h
+(nodal)e(graph)g(and)h(then)g(uses)i Fz(METIS)p 2642
+3892 V 30 w(P)m(ar)s(tGr)o(aphKw)o(a)n(y)f FL(to)f(compute)f(a)i
+(parti-)208 4002 y(tioning)f(of)h(the)g(nodes.)28 b(This)22
+b(partitioning)d(of)i(nodes)g(is)h(then)f(used)g(to)h(compute)e(a)h
+(partitioning)f(for)g(the)i(elements.)28 b(This)22 b(is)208
+4111 y(done)d(by)i(assigning)f(each)h(element)f(to)h(the)g(partition)f
+(in)h(which)g(the)g(majority)f(of)g(its)i(nodes)e(belong)g(to)h
+(\(subject)f(to)h(balance)208 4221 y(constraints\).)1908
+5649 y(34)p eop
+%%Page: 35 35
+35 34 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(P)n(ar)r(tMeshDual)20
+b FL(\(int)g(*ne,)g(int)g(*nn,)f(idxtype)g(*elmnts,)g(int)i(*etype,)e
+(int)h(*num\003ag,)e(int)j(*nparts,)e(int)h(*edgecut,)857
+193 y(idxtype)f(*epart,)g(idxtype)g(*npart\))0 452 y
+FB(Description)208 561 y FL(This)e(function)f(is)j(used)e(to)h
+(partition)e(a)i(mesh)f(into)h Ft(k)23 b FL(equal-size)16
+b(parts.)24 b(It)18 b(pro)o(vides)e(the)h(functionality)f(of)h(the)h
+Fp(partdmesh)208 671 y FL(program.)0 847 y FB(P)n(arameter)o(s)208
+966 y FC(ne)290 b FL(The)20 b(number)e(of)i(elements)g(in)h(the)f
+(mesh.)208 1109 y FC(nn)281 b FL(The)20 b(number)e(of)i(nodes)g(in)g
+(the)g(mesh.)208 1252 y FC(elmnts)138 b FL(The)20 b(element)g(node)f
+(array)g(storing)g(the)i(mesh)f(as)h(described)d(in)j(Section)f(5.2.)
+208 1395 y FC(etype)183 b FL(Indicates)20 b(the)g(type)g(of)f(the)i
+(elements)f(in)g(the)g(mesh.)25 b Fs(etype)20 b FL(can)g(tak)o(e)g(the)
+g(follo)n(wing)f(v)n(alues:)581 1538 y(1)83 b(The)20
+b(elements)f(are)i(triangles.)581 1664 y(2)83 b(The)20
+b(elements)f(are)i(tetrahedra.)581 1790 y(3)83 b(The)20
+b(elements)f(are)i(he)o(xahedra)c(\(bricks\).)581 1916
+y(4)83 b(The)20 b(elements)f(are)i(quadrilaterals.)208
+2059 y FC(num\003ag)82 b FL(Used)22 b(to)h(indicate)e(which)h
+(numbering)d(scheme)j(is)h(used)f(for)g(the)g(element)f(node)g(array)-5
+b(.)30 b Fs(num\003a)o(g)20 b FL(can)i(tak)o(e)h(the)581
+2169 y(follo)n(wing)c(tw)o(o)h(v)n(alues:)581 2311 y(0)83
+b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h(from)e(0)581
+2438 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j(assumed)e(that)i
+(starts)g(from)e(1)208 2580 y FC(nparts)142 b FL(The)20
+b(number)e(of)i(parts)g(to)h(partition)e(the)h(mesh.)208
+2723 y FC(edgecut)100 b FL(Upon)20 b(successful)h(completion,)f(this)i
+(v)n(ariable)e(stores)h(the)g(number)f(of)h(edges)g(that)g(are)g(cut)g
+(by)g(the)g(partition)f(in)581 2833 y(the)g(dual)g(graph.)208
+2976 y FC(epart)183 b FL(This)18 b(is)h(a)g(v)o(ector)d(of)i(size)h
+Fs(ne)e FL(that)h(upon)f(successful)h(completion)e(stores)i(the)g
+(partition)f(v)o(ector)g(for)g(the)h(elements)581 3085
+y(of)31 b(the)f(mesh.)57 b(The)30 b(numbering)e(of)j(this)g(v)o(ector)e
+(starts)j(from)e(either)g(0)h(or)f(1,)k(depending)28
+b(on)i(the)h(v)n(alue)f(of)581 3195 y Fs(num\003a)o(g)p
+FL(.)208 3337 y FC(npart)174 b FL(This)19 b(is)g(a)g(v)o(ector)e(of)h
+(size)i Fs(nn)e FL(that)g(upon)f(successful)h(completion)f(stores)i
+(the)f(partition)g(v)o(ector)f(for)h(the)g(nodes)g(of)581
+3447 y(the)i(mesh.)25 b(The)19 b(numbering)f(of)h(this)i(v)o(ector)d
+(starts)j(from)e(either)g(0)h(or)g(1,)g(depending)d(on)j(the)g(v)n
+(alue)f(of)h Fs(num\003a)o(g)p FL(.)0 3623 y FB(Note)208
+3733 y FL(This)j(function)e(con)m(v)o(erts)h(the)h(mesh)g(into)f(a)i
+(dual)f(graph)e(and)i(then)g(uses)g Fz(METIS)p 2631 3733
+V 31 w(P)m(ar)s(tGr)o(aphKw)o(a)n(y)g FL(to)g(compute)f(a)h(parti-)208
+3842 y(tioning)c(of)h(the)g(elements.)25 b(This)20 b(partitioning)f(of)
+h(elements)g(is)h(then)f(used)g(to)g(compute)f(a)i(partitioning)d(for)i
+(the)g(nodes.)k(This)208 3952 y(is)d(done)f(by)g(assigning)g(each)g
+(node)g(to)h(the)g(partition)e(in)i(which)f(the)h(majority)f(of)g(its)i
+(incident)e(elements)g(belong)f(to)i(\(subject)208 4061
+y(to)f(balance)f(constraints\).)1908 5649 y(35)p eop
+%%Page: 36 36
+36 35 bop 0 83 a Fr(5.6)100 b(Spar)o(se)29 b(Matrix)f(Reor)n(dering)f
+(Routines)0 242 y FB(METIS)p 258 242 25 4 v 31 w(Edg)q(eND)20
+b FL(\(int)g(*n,)g(idxtype)e(*xadj,)h(idxtype)g(*adjnc)o(y)-5
+b(,)18 b(int)i(*num\003ag,)f(int)h(*options,)f(idxtype)f(*perm,)h
+(idxtype)g(*iperm\))0 501 y FB(Description)208 611 y
+FL(This)25 b(function)f(computes)h(\002ll)h(reducing)e(orderings)f(of)j
+(sparse)f(matrices)h(using)f(the)g(multile)n(v)o(el)g(nested)g
+(dissection)g(algo-)208 721 y(rithm.)f(It)c(pro)o(vides)f(the)h
+(functionality)e(of)i(the)g Fp(oemetis)g FL(program.)0
+897 y FB(P)n(arameter)o(s)208 1016 y FC(n)327 b FL(The)20
+b(number)e(of)i(v)o(ertices)g(in)g(the)h(graph.)208 1133
+y FC(xadj,)e(adjncy)581 1242 y FL(The)h(adjacenc)o(y)e(structure)i(of)g
+(the)g(graph)f(as)i(described)d(in)j(Section)f(5.1.)208
+1385 y FC(num\003ag)82 b FL(Used)22 b(to)f(indicate)g(which)g
+(numbering)d(scheme)j(is)h(used)f(for)g(the)g(adjacenc)o(y)f(structure)
+g(of)h(the)g(graph.)27 b Fs(num\003a)o(g)581 1495 y FL(can)20
+b(tak)o(e)g(the)h(follo)n(wing)d(tw)o(o)j(v)n(alues:)581
+1638 y(0)83 b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h
+(from)e(0)581 1764 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j
+(assumed)e(that)i(starts)g(from)e(1)208 1907 y FC(options)114
+b FL(This)22 b(is)g(an)f(array)f(of)h(5)h(inte)o(gers)e(that)h(is)i
+(used)e(to)g(pass)h(parameters)e(for)h(the)g(v)n(arious)f(phases)h(of)g
+(the)g(algorithm.)581 2016 y(If)j Fs(options[0]=0)e FL(then)h(def)o
+(ault)g(v)n(alues)g(are)h(used.)34 b(If)24 b Fs(options[0]=1)p
+FL(,)f(then)g(the)g(remaining)f(four)h(elements)g(of)581
+2126 y Fs(options)c FL(are)i(interpreted)d(as)j(follo)n(ws:)581
+2269 y(options[1])108 b(Determined)19 b(the)h(matching)f(type.)24
+b(Possible)d(v)n(alues)f(are:)1033 2395 y(1)83 b(Random)19
+b(Matching)g(\(RM\))1033 2521 y(2)83 b(Hea)n(vy-Edge)18
+b(Matching)h(\(HEM\))1033 2647 y(3)83 b(Sorted)19 b(Hea)n(vy-Edge)f
+(Matching)h(\(SHEM\))h(\(Def)o(ault\))1033 2773 y(Experiments)f(has)h
+(sho)n(wn)g(that)g(both)f(HEM)h(and)g(SHEM)g(perform)f(quite)g(well.)
+581 2900 y(options[2])108 b(Determines)20 b(the)g(algorithm)f(used)g
+(during)g(initial)i(partitioning.)h(Possible)f(v)n(alues)f(are:)1033
+3026 y(1)83 b(Re)o(gion)19 b(Gro)n(wing)g(\(Def)o(ault\))581
+3152 y(options[3])108 b(Determines)20 b(the)g(algorithm)f(used)g(for)h
+(re\002nement.)k(Possible)c(v)n(alues)g(are:)1033 3278
+y(1)83 b(Early-Exit)18 b(Boundary)h(FM)h(re\002nement)f(\(Def)o(ault\))
+581 3404 y(options[4])108 b(Used)21 b(for)e(deb)n(ugging)f(purposes.)23
+b(Al)o(w)o(ays)e(set)g(it)g(to)f(0)h(\(Def)o(ault\).)208
+3521 y FC(perm,)f(iperm)581 3631 y FL(These)25 b(are)g(v)o(ectors,)f
+(each)h(of)g(size)g Fs(n)p FL(.)39 b(Upon)24 b(successful)h
+(completion,)f(the)o(y)g(store)g(the)h(\002ll-reducing)e(permu-)581
+3740 y(tation)j(and)g(in)m(v)o(erse-permutation.)39 b(Let)34
+b Ft(A)29 b FL(be)d(the)g(original)f(matrix)h(and)34
+b Ft(A)2868 3710 y Fe(0)2915 3740 y FL(be)27 b(the)f(permuted)e
+(matrix.)43 b(The)581 3850 y(arrays)21 b Fs(perm)g FL(and)f
+Fs(iperm)h FL(are)g(de\002ned)f(as)i(follo)n(ws.)27 b(Ro)n(w)21
+b(\(column\))d Ft(i)30 b FL(of)f Ft(A)2836 3820 y Fe(0)2878
+3850 y FL(is)22 b(the)f(perm)o FM(T)o Ft(i)9 b FM(U)20
+b FL(ro)n(w)h(\(column\))e(of)589 3959 y Ft(A)r FL(,)j(and)f(ro)n(w)g
+(\(column\))d Ft(i)31 b FL(of)e Ft(A)24 b FL(is)e(the)g(iperm)n
+FM(T)o Ft(i)9 b FM(U)21 b FL(ro)n(w)g(\(column\))f(of)29
+b Ft(A)2659 3929 y Fe(0)2680 3959 y FL(.)g(The)21 b(numbering)e(of)i
+(this)h(v)o(ector)f(starts)581 4069 y(from)e(either)h(0)g(or)g(1,)g
+(depending)e(on)i(the)g(v)n(alue)f(of)h Fs(num\003a)o(g)p
+FL(.)0 4245 y FB(Note)208 4355 y FL(This)25 b(function)f(computes)g
+(the)h(v)o(erte)o(x)f(separator)g(from)g(the)h(edge)g(separator)f
+(using)h(a)g(minimum)f(co)o(v)o(er)g(algorithm.)38 b(This)208
+4464 y(function)21 b(should)i(be)g(used)h(only)f(in)g(ordering)f(lar)o
+(ge)g(graphs)h(arising)g(in)h(3D)f(\002nite)h(element)f(applications.)
+34 b(In)23 b(general)g(the)208 4574 y Fz(METIS)p 466
+4574 V 30 w(NodeND)e FL(routine)e(should)g(be)h(preferred,)e(as)j(it)g
+(produces)d(better)i(orderings.)1908 5649 y(36)p eop
+%%Page: 37 37
+37 36 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(NodeND)20
+b FL(\(int)g(*n,)f(idxtype)g(*xadj,)g(idxtype)g(*adjnc)o(y)-5
+b(,)18 b(int)i(*num\003ag,)e(int)j(*options,)d(idxtype)h(*perm,)g
+(idxtype)g(*iperm\))0 342 y FB(Description)208 452 y
+FL(This)25 b(function)f(computes)h(\002ll)h(reducing)e(orderings)f(of)j
+(sparse)f(matrices)h(using)f(the)g(multile)n(v)o(el)g(nested)g
+(dissection)g(algo-)208 561 y(rithm.)f(It)c(pro)o(vides)f(the)h
+(functionality)e(of)i(the)g Fp(onmetis)g FL(program.)0
+737 y FB(P)n(arameter)o(s)208 857 y FC(n)327 b FL(The)20
+b(number)e(of)i(v)o(ertices)g(in)g(the)h(graph.)208 973
+y FC(xadj,)e(adjncy)581 1083 y FL(The)h(adjacenc)o(y)e(structure)i(of)g
+(the)g(graph)f(as)i(described)d(in)j(Section)f(5.1.)208
+1226 y FC(num\003ag)82 b FL(Used)22 b(to)f(indicate)g(which)g
+(numbering)d(scheme)j(is)h(used)f(for)g(the)g(adjacenc)o(y)f(structure)
+g(of)h(the)g(graph.)27 b Fs(num\003a)o(g)581 1335 y FL(can)20
+b(tak)o(e)g(the)h(follo)n(wing)d(tw)o(o)j(v)n(alues:)581
+1478 y(0)83 b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h
+(from)e(0)581 1604 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j
+(assumed)e(that)i(starts)g(from)e(1)208 1747 y FC(options)114
+b FL(This)22 b(is)g(an)f(array)f(of)h(8)h(inte)o(gers)e(that)h(is)i
+(used)e(to)g(pass)h(parameters)e(for)h(the)g(v)n(arious)f(phases)h(of)g
+(the)g(algorithm.)581 1857 y(If)g Fs(options[0]=0)e FL(then)h(def)o
+(ault)g(v)n(alues)g(are)h(used.)26 b(If)21 b Fs(options[0]=1)p
+FL(,)e(then)h(the)h(remaining)e(se)n(v)o(en)g(elements)i(of)581
+1966 y Fs(options)e FL(are)i(interpreted)d(as)j(follo)n(ws:)581
+2109 y(options[1])108 b(Determines)20 b(the)g(matching)f(type.)24
+b(Possible)d(v)n(alues)e(are:)1033 2235 y(1)83 b(Random)19
+b(Matching)g(\(RM\))1033 2362 y(2)83 b(Hea)n(vy-Edge)18
+b(Matching)h(\(HEM\))1033 2488 y(3)83 b(Sorted)19 b(Hea)n(vy-Edge)f
+(Matching)h(\(SHEM\))h(\(Def)o(ault\))1033 2614 y(Experiments)14
+b(ha)n(v)o(e)h(sho)n(wn)g(that)h(all)h(three)e(matching)f(schemes)i
+(perform)e(quite)h(well.)24 b(In)16 b(general)1033 2724
+y(SHEM)22 b(is)h(f)o(aster)e(and)g(RM)i(is)f(slo)n(wer)m(,)f(b)n(ut)h
+(feel)g(free)f(to)g(e)o(xperiment)f(with)i(the)f(other)g(matching)1033
+2833 y(schemes.)581 2959 y(options[2])108 b(Determines)20
+b(the)g(algorithm)f(used)g(during)g(initial)i(partitioning.)h(Possible)
+f(v)n(alues)f(are:)1033 3086 y(1)83 b(Edge-based)18 b(re)o(gion)g(gro)n
+(wing)h(\(Def)o(ault\))1033 3212 y(2)83 b(Node-based)18
+b(re)o(gion)h(gro)n(wing)581 3338 y(options[3])108 b(Determines)20
+b(the)g(algorithm)f(used)g(for)h(re\002nement.)k(Possible)c(v)n(alues)g
+(are:)1033 3464 y(1)83 b(T)-7 b(w)o(o-sided)19 b(node)g(FM)i
+(re\002nement)1033 3590 y(2)83 b(One-sided)19 b(node)g(FM)i
+(re\002nement)d(\(Def)o(ault\))1033 3717 y(One-sided)i(FM)h
+(re\002nement)f(is)i(f)o(aster)f(than)g(tw)o(o-sided,)f(b)n(ut)h(in)g
+(some)f(cases)i(tw)o(o-sided)e(re\002ne-)1033 3826 y(ment)g(may)g
+(produce)e(better)i(orderings.)j(Feel)d(free)g(to)h(e)o(xperiment)d
+(with)i(this)h(option.)581 3952 y(options[4])108 b(Used)21
+b(for)e(deb)n(ugging)f(purposes.)23 b(Al)o(w)o(ays)e(set)g(it)g(to)f(0)
+h(\(Def)o(ault\).)581 4079 y(options[5])108 b(Used)17
+b(to)f(select)h(whether)e(or)h(not)f(to)i(compress)e(the)h(graph)f(and)
+g(to)i(order)d(connected)h(components)1033 4188 y(separately)-5
+b(.)24 b(The)c(possible)g(v)n(alues)f(and)h(their)g(meaning)f(are)h(as)
+h(follo)n(ws.)1033 4314 y(0)83 b(Do)32 b(not)h(try)f(to)h(compress)f
+(the)h(graph)e(and)h(do)g(not)h(order)e(each)h(connected)f(component)
+1158 4424 y(separately)-5 b(.)1033 4550 y(1)83 b(T)m(ry)23
+b(to)i(compress)e(the)h(graph.)36 b(\(A)24 b(compressed)f(graph)f(is)j
+(actually)f(formed)e(if)j(the)f(size)h(of)1158 4660 y(the)20
+b(graph)f(can)h(be)g(reduced)e(by)i(at)h(least)g(15\045\))e(\(Def)o
+(ault\).)1033 4786 y(2)83 b(Order)28 b(each)h(connected)e(component)f
+(of)j(the)g(graph)e(separately)-5 b(.)50 b(This)30 b(option)d(is)j
+(partic-)1158 4895 y(ularly)25 b(useful)h(when)f(after)h(a)h(fe)n(w)f
+(le)n(v)o(els)g(of)g(nested)f(dissection,)i(the)g(graph)d(breaks)i(up)f
+(in)1158 5005 y(man)o(y)16 b(smaller)i(disconnected)e(subgraphs.)22
+b(This)c(is)g(true)g(for)f(certain)g(types)g(of)h(LP)g(matrices.)1033
+5131 y(3)83 b(T)m(ry)19 b(to)i(compress)e(the)h(graph)f(and)h(also)g
+(order)f(each)h(connected)e(component)g(separately)-5
+b(.)1908 5649 y(37)p eop
+%%Page: 38 38
+38 37 bop 581 83 a FL(options[6])108 b(Used)20 b(to)f(control)f
+(whether)g(or)h(not)g(the)g(ordering)e(algorithm)h(should)g(remo)o(v)o
+(e)f(an)o(y)i(v)o(ertices)f(with)1033 193 y(high)j(de)o(gree)e(\()p
+Fs(i.e)p FL(.,)i(dense)g(columns\).)27 b(This)21 b(is)h(particularly)e
+(helpful)g(for)g(certain)h(classes)h(of)f(LP)1033 302
+y(matrices,)k(in)f(which)g(there)f(a)i(fe)n(w)f(v)o(ertices)g(that)g
+(are)g(connected)e(to)j(man)o(y)e(other)g(v)o(ertices.)36
+b(By)1033 412 y(remo)o(ving)20 b(these)j(v)o(ertices)e(prior)h(to)g
+(ordering,)f(the)h(quality)g(and)f(the)i(amount)e(of)h(time)g(required)
+1033 521 y(to)f(do)e(the)i(ordering)d(impro)o(v)o(es.)23
+b(The)c(possible)h(v)n(alues)g(are)g(as)h(follo)n(ws:)1033
+648 y(0)83 b(Do)20 b(not)g(remo)o(v)o(e)e(an)o(y)h(v)o(ertices)h(\(Def)
+o(ault\))1035 774 y Ft(x)91 b FL(Where)34 b Ft(x)54 b
+Fu(>)46 b FL(0,)36 b(instructs)d(the)g(algorithm)e(to)i(remo)o(v)o(e)e
+(an)o(y)h(v)o(ertices)g(whose)g(de)o(gree)g(is)1158 883
+y(greater)25 b(than)h(0)p Fu(:)p FL(1)21 b FM(\003)k
+Ft(x)31 b FM(\003)23 b Fu(.)p FL(a)n(v)o(erage)c(de)o(gree\))m(.)44
+b(F)o(or)26 b(e)o(xample)e(if)29 b Ft(x)41 b FM(D)34
+b FL(40,)27 b(and)f(the)g(a)n(v)o(erage)1158 993 y(de)o(gree)18
+b(is)i(5,)f(then)g(the)g(algorithm)e(will)j(remo)o(v)o(e)e(all)h(v)o
+(ertices)g(with)h(de)o(gree)d(greater)h(than)h(20.)1158
+1103 y(The)f(v)o(ertices)g(that)g(are)g(remo)o(v)o(ed)e(are)i(ordered)f
+(last)i(\()p Fs(i.e)o FL(.,)g(the)o(y)f(are)g(automatically)f(placed)g
+(in)1158 1212 y(the)22 b(top-le)n(v)o(el)f(separator\).)31
+b(Good)22 b(v)n(alues)g(are)h(often)f(in)g(the)h(range)f(of)g(60)g(to)h
+(200)f(\()p Fs(i.e)o FL(.,)i(6)e(to)1158 1322 y(20)e(times)g(more)g
+(than)f(the)h(a)n(v)o(erage\).)581 1448 y(options[7])108
+b(Used)23 b(to)g(determine)e(ho)n(w)h(man)o(y)g(separators)g(to)h
+(\002nd)f(at)h(each)g(step)g(of)f(nested)h(dissection.)32
+b(The)1033 1558 y(lar)o(ger)16 b(the)i(number)d(of)i(separators)g
+(found)f(at)h(each)h(step,)g(the)f(higher)f(the)h(runtime)g(and)g
+(better)g(the)1033 1667 y(quality)i(is)h(\(in)f(general\).)k(The)18
+b(def)o(ault)h(v)n(alue)f(is)i(1,)f(unless)h(the)f(graph)f(has)h(been)f
+(compressed)g(by)1033 1777 y(more)g(than)h(a)g(f)o(actor)g(of)f(2,)h
+(in)g(which)g(case)g(it)h(becomes)e(2.)25 b(Reasonable)18
+b(v)n(alues)h(are)f(in)i(the)f(range)1033 1886 y(of)h(1)g(to)h(5.)k(F)o
+(or)20 b(most)g(problems,)e(a)j(v)n(alue)e(of)h(5)h(increases)f(the)g
+(runtime)f(by)h(a)g(f)o(actor)g(of)g(3.)208 2003 y FC(perm,)g(iperm)581
+2113 y FL(These)25 b(are)g(v)o(ectors,)f(each)h(of)g(size)g
+Fs(n)p FL(.)39 b(Upon)24 b(successful)h(completion,)f(the)o(y)g(store)g
+(the)h(\002ll-reducing)e(permu-)581 2222 y(tation)j(and)g(in)m(v)o
+(erse-permutation.)39 b(Let)34 b Ft(A)29 b FL(be)d(the)g(original)f
+(matrix)h(and)34 b Ft(A)2868 2192 y Fe(0)2915 2222 y
+FL(be)27 b(the)f(permuted)e(matrix.)43 b(The)581 2332
+y(arrays)21 b Fs(perm)g FL(and)f Fs(iperm)h FL(are)g(de\002ned)f(as)i
+(follo)n(ws.)27 b(Ro)n(w)21 b(\(column\))d Ft(i)30 b
+FL(of)f Ft(A)2836 2302 y Fe(0)2878 2332 y FL(is)22 b(the)f(perm)o
+FM(T)o Ft(i)9 b FM(U)20 b FL(ro)n(w)h(\(column\))e(of)589
+2441 y Ft(A)r FL(,)j(and)f(ro)n(w)g(\(column\))d Ft(i)31
+b FL(of)e Ft(A)24 b FL(is)e(the)g(iperm)n FM(T)o Ft(i)9
+b FM(U)21 b FL(ro)n(w)g(\(column\))f(of)29 b Ft(A)2659
+2411 y Fe(0)2680 2441 y FL(.)g(The)21 b(numbering)e(of)i(this)h(v)o
+(ector)f(starts)581 2551 y(from)e(either)h(0)g(or)g(1,)g(depending)e
+(on)i(the)g(v)n(alue)f(of)h Fs(num\003a)o(g)p FL(.)0
+2727 y FB(Note)208 2837 y FL(This)25 b(function)g(computes)f(the)i(v)o
+(erte)o(x)e(separator)h(directly)g(by)g(using)g(a)h(multile)n(v)o(el)f
+(algorithm.)40 b(This)26 b(function)e(produces)208 2946
+y(high)19 b(quality)g(orderings)g(and)g(should)g(be)i(preferred)d(o)o
+(v)o(er)g Fz(METIS)p 2192 2946 25 4 v 31 w(EdgeND)p FL(.)1908
+5649 y(38)p eop
+%%Page: 39 39
+39 38 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(NodeWND)20
+b FL(\(int)g(*n,)g(idxtype)f(*xadj,)g(idxtype)f(*adjnc)o(y)-5
+b(,)18 b(idxtype)h(*vwgt,)g(int)h(*num\003ag,)f(int)h(*options,)710
+193 y(idxtype)f(*perm,)g(idxtype)f(*iperm\))0 452 y FB(Description)208
+561 y FL(This)25 b(function)f(computes)h(\002ll)h(reducing)e(orderings)
+f(of)j(sparse)f(matrices)h(using)f(the)g(multile)n(v)o(el)g(nested)g
+(dissection)g(algo-)208 671 y(rithm.)f(It)19 b(is)h(similar)f(to)g
+Fz(METIS)p 1171 671 V 31 w(NodeWND)h FL(b)n(ut)f(it)g(assumes)h(that)f
+(the)g(compression)e(has)i(been)f(already)g(performed)f(prior)208
+780 y(to)22 b(calling)f(this)i(routine.)29 b(It)22 b(is)h(particularly)
+d(suited)i(for)f(ordering)f(v)o(ery)h(lar)o(ge)g(matrices)g(in)h(which)
+g(the)g(compressed)e(matrix)208 890 y(is)h(kno)n(wn)d(a)j(priori.)0
+1066 y FB(P)n(arameter)o(s)208 1186 y FC(n)327 b FL(The)20
+b(number)e(of)i(v)o(ertices)g(in)g(the)h(graph.)208 1302
+y FC(xadj,)e(adjncy)581 1412 y FL(The)h(adjacenc)o(y)e(structure)i(of)g
+(the)g(graph)f(as)i(described)d(in)j(Section)f(5.1.)208
+1555 y FC(vwgt)201 b FL(The)20 b(weight)g(of)g(the)g(v)o(ertices.)208
+1697 y FC(num\003ag)82 b FL(Used)22 b(to)f(indicate)g(which)g
+(numbering)d(scheme)j(is)h(used)f(for)g(the)g(adjacenc)o(y)f(structure)
+g(of)h(the)g(graph.)27 b Fs(num\003a)o(g)581 1807 y FL(can)20
+b(tak)o(e)g(the)h(follo)n(wing)d(tw)o(o)j(v)n(alues:)581
+1950 y(0)83 b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h
+(from)e(0)581 2076 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j
+(assumed)e(that)i(starts)g(from)e(1)208 2219 y FC(options)114
+b FL(This)22 b(is)g(an)f(array)f(of)h(5)h(inte)o(gers)e(that)h(is)i
+(used)e(to)g(pass)h(parameters)e(for)h(the)g(v)n(arious)f(phases)h(of)g
+(the)g(algorithm.)581 2328 y(If)j Fs(options[0]=0)e FL(then)h(def)o
+(ault)g(v)n(alues)g(are)h(used.)34 b(If)24 b Fs(options[0]=1)p
+FL(,)f(then)g(the)g(remaining)f(four)h(elements)g(of)581
+2438 y Fs(options)c FL(are)i(interpreted)d(as)j(follo)n(ws:)581
+2581 y(options[1])108 b(Determines)20 b(the)g(matching)f(type.)24
+b(Possible)d(v)n(alues)e(are:)1033 2707 y(1)83 b(Random)19
+b(Matching)g(\(RM\))1033 2833 y(2)83 b(Hea)n(vy-Edge)18
+b(Matching)h(\(HEM\))1033 2959 y(3)83 b(Sorted)19 b(Hea)n(vy-Edge)f
+(Matching)h(\(SHEM\))h(\(Def)o(ault\))1033 3086 y(Experiments)14
+b(ha)n(v)o(e)h(sho)n(wn)g(that)h(all)h(three)e(matching)f(schemes)i
+(perform)e(quite)h(well.)24 b(In)16 b(general)1033 3195
+y(SHEM)22 b(is)h(f)o(aster)e(and)g(RM)i(is)f(slo)n(wer)m(,)f(b)n(ut)h
+(feel)g(free)f(to)g(e)o(xperiment)f(with)i(the)f(other)g(matching)1033
+3305 y(schemes.)581 3431 y(options[2])108 b(Determines)20
+b(the)g(algorithm)f(used)g(during)g(initial)i(partitioning.)h(Possible)
+f(v)n(alues)f(are:)1033 3557 y(1)83 b(Edge-based)18 b(re)o(gion)g(gro)n
+(wing)h(\(Def)o(ault\))1033 3683 y(2)83 b(Node-based)18
+b(re)o(gion)h(gro)n(wing)581 3810 y(options[3])108 b(Determines)20
+b(the)g(algorithm)f(used)g(for)h(re\002nement.)k(Possible)c(v)n(alues)g
+(are:)1033 3936 y(1)83 b(T)-7 b(w)o(o-sided)19 b(node)g(FM)i
+(re\002nement)1033 4062 y(2)83 b(One-sided)19 b(node)g(FM)i
+(re\002nement)d(\(Def)o(ault\))1033 4188 y(One-sided)i(FM)h
+(re\002nement)f(is)i(f)o(aster)f(than)g(tw)o(o-sided,)f(b)n(ut)h(in)g
+(some)f(cases)i(tw)o(o-sided)e(re\002ne-)1033 4298 y(ment)g(may)g
+(produce)e(better)i(orderings.)j(Feel)d(free)g(to)h(e)o(xperiment)d
+(with)i(this)h(option.)581 4424 y(options[4])108 b(Used)21
+b(for)e(deb)n(ugging)f(purposes.)23 b(Al)o(w)o(ays)e(set)g(it)g(to)f(0)
+h(\(Def)o(ault\).)208 4541 y FC(perm,)f(iperm)581 4650
+y FL(These)25 b(are)g(v)o(ectors,)f(each)h(of)g(size)g
+Fs(n)p FL(.)39 b(Upon)24 b(successful)h(completion,)f(the)o(y)g(store)g
+(the)h(\002ll-reducing)e(permu-)581 4760 y(tation)j(and)g(in)m(v)o
+(erse-permutation.)39 b(Let)34 b Ft(A)29 b FL(be)d(the)g(original)f
+(matrix)h(and)34 b Ft(A)2868 4730 y Fe(0)2915 4760 y
+FL(be)27 b(the)f(permuted)e(matrix.)43 b(The)581 4869
+y(arrays)21 b Fs(perm)g FL(and)f Fs(iperm)h FL(are)g(de\002ned)f(as)i
+(follo)n(ws.)27 b(Ro)n(w)21 b(\(column\))d Ft(i)30 b
+FL(of)f Ft(A)2836 4839 y Fe(0)2878 4869 y FL(is)22 b(the)f(perm)o
+FM(T)o Ft(i)9 b FM(U)20 b FL(ro)n(w)h(\(column\))e(of)589
+4979 y Ft(A)r FL(,)j(and)f(ro)n(w)g(\(column\))d Ft(i)31
+b FL(of)e Ft(A)24 b FL(is)e(the)g(iperm)n FM(T)o Ft(i)9
+b FM(U)21 b FL(ro)n(w)g(\(column\))f(of)29 b Ft(A)2659
+4949 y Fe(0)2680 4979 y FL(.)g(The)21 b(numbering)e(of)i(this)h(v)o
+(ector)f(starts)581 5089 y(from)e(either)h(0)g(or)g(1,)g(depending)e
+(on)i(the)g(v)n(alue)f(of)h Fs(num\003a)o(g)p FL(.)1908
+5649 y(39)p eop
+%%Page: 40 40
+40 39 bop 0 83 a Fr(5.7)100 b(A)m(uxiliar)q(y)28 b(Routines)0
+242 y FB(METIS)p 258 242 25 4 v 31 w(MeshT)-7 b(oNodal)20
+b FL(\(int)g(*ne,)f(int)i(*nn,)e(idxtype)g(*elmnts,)g(int)i(*etype,)d
+(int)j(*num\003ag,)d(idxtype)h(*nxadj,)f(idxtype)h(*nadjnc)o(y\))0
+501 y FB(Description)208 611 y FL(This)26 b(function)f(is)i(used)f(to)g
+(con)m(v)o(ert)f(a)h(mesh)g(into)g(a)h(nodal)f(graph,)g(in)g(a)h
+(format)e(suitable)h(for)i Fz(M)l FG(E)-17 b Fz(T)g FG(I)p
+Fz(S)r(lib)p FL(.)46 b(It)27 b(pro)o(vides)e(the)208
+721 y(function)18 b(of)i(the)g Fp(mesh2nodal)f FL(program.)0
+897 y FB(P)n(arameter)o(s)208 1016 y FC(ne)290 b FL(The)20
+b(number)e(of)i(elements)g(in)h(the)f(mesh.)208 1159
+y FC(nn)281 b FL(The)20 b(number)e(of)i(nodes)g(in)g(the)g(mesh.)208
+1302 y FC(elmnts)138 b FL(The)20 b(element)g(node)f(array)g(storing)g
+(the)i(mesh)f(as)h(described)d(in)j(Section)f(5.2.)208
+1445 y FC(etype)183 b FL(Indicates)20 b(the)g(type)g(of)f(the)i
+(elements)f(in)g(the)g(mesh.)25 b Fs(etype)20 b FL(can)g(tak)o(e)g(the)
+g(follo)n(wing)f(v)n(alues:)581 1587 y(1)83 b(The)20
+b(elements)f(are)i(triangles.)581 1714 y(2)83 b(The)20
+b(elements)f(are)i(tetrahedra.)581 1840 y(3)83 b(The)20
+b(elements)f(are)i(he)o(xahedra)c(\(bricks\).)581 1966
+y(4)83 b(The)20 b(elements)f(are)i(quadrilaterals.)208
+2109 y FC(num\003ag)82 b FL(Used)22 b(to)h(indicate)e(which)h
+(numbering)d(scheme)j(is)h(used)f(for)g(the)g(element)f(node)g(array)-5
+b(.)30 b Fs(num\003a)o(g)20 b FL(can)i(tak)o(e)h(the)581
+2218 y(follo)n(wing)c(tw)o(o)h(v)n(alues:)581 2361 y(0)83
+b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h(from)e(0)581
+2487 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j(assumed)e(that)i
+(starts)g(from)e(1)208 2604 y FC(nxadj,)g(nadjncy)581
+2714 y FL(These)29 b(arrays)f(store)g(the)h(adjacenc)o(y)e(structure)h
+(of)g(the)h(nodal)e(graph.)49 b(The)29 b(user)f(must)h(pro)o(vide)d
+(arrays)i(that)581 2823 y(are)c(suf)n(\002ciently)g(lar)o(ge)f(to)i
+(store)f(the)g(graph.)36 b(The)24 b(size)h(of)f(array)f
+Fs(nxadj)h FL(is)h Fs(nn+1)e FL(where)h(the)g(size)h(of)f
+Fs(nadjncy)581 2933 y FL(depends)i(on)g(the)h(type)f(of)h(the)g(mesh.)
+44 b(F)o(or)27 b(triangular)n(-element)d(and)i(he)o(xahedra-element)d
+(meshes,)28 b Fs(nadjncy)581 3042 y FL(should)19 b(be)g(at)h(least)h(6)
+15 b FM(\003)h Fs(nn)o FL(,)k(for)f(quadrilateral-element)e(meshes,)i
+Fs(nadjncy)f FL(should)g(be)i(at)g(least)g(4)c FM(\003)g
+Fs(nn)o FL(,)k(and)f(for)581 3152 y(tetrahedra-element)e(meshes,)j
+Fs(nadjncy)f FL(should)g(be)h(at)h(least)g(15)c FM(\003)i
+Fs(nn)o FL(.)0 3328 y FB(Note)208 3438 y FL(The)k(nodal)h(graph)e(is)k
+(de\002ned)d(as)i(the)f(graph)f(in)h(which)g(each)g(v)o(erte)o(x)e(of)i
+(the)h(graph)d(corresponds)g(to)j(a)f(node)f(in)i(the)f(mesh,)208
+3547 y(and)19 b(tw)o(o)i(v)o(ertices)e(are)h(connected)f(by)h(an)g
+(edge)f(if)i(the)f(corresponding)d(nodes)i(a)i(connected)d(by)i(an)g
+(element.)1908 5649 y(40)p eop
+%%Page: 41 41
+41 40 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(MeshT)-7
+b(oDual)20 b FL(\(int)g(*ne,)g(int)g(*nn,)f(idxtype)g(*elmnts,)g(int)i
+(*etype,)e(int)h(*num\003ag,)e(idxtype)h(*dxadj,)g(idxtype)f(*dadjnc)o
+(y\))0 342 y FB(Description)208 452 y FL(This)28 b(function)e(is)j
+(used)f(to)h(con)m(v)o(ert)d(a)i(mesh)g(into)g(a)h(dual)f(graph,)g(in)g
+(a)h(format)e(suitable)h(for)i Fz(M)l FG(E)-17 b Fz(T)g
+FG(I)p Fz(S)r(lib)p FL(.)52 b(It)28 b(pro)o(vides)f(the)208
+561 y(function)18 b(of)i(the)g Fp(mesh2nodal)f FL(program.)0
+737 y FB(P)n(arameter)o(s)208 857 y FC(ne)290 b FL(The)20
+b(number)e(of)i(elements)g(in)h(the)f(mesh.)208 1000
+y FC(nn)281 b FL(The)20 b(number)e(of)i(nodes)g(in)g(the)g(mesh.)208
+1142 y FC(elmnts)138 b FL(The)20 b(element)g(node)f(array)g(storing)g
+(the)i(mesh)f(as)h(described)d(in)j(Section)f(5.2.)208
+1285 y FC(etype)183 b FL(Indicates)20 b(the)g(type)g(of)f(the)i
+(elements)f(in)g(the)g(mesh.)25 b Fs(etype)20 b FL(can)g(tak)o(e)g(the)
+g(follo)n(wing)f(v)n(alues:)581 1428 y(1)83 b(The)20
+b(elements)f(are)i(triangles.)581 1554 y(2)83 b(The)20
+b(elements)f(are)i(tetrahedra.)581 1680 y(3)83 b(The)20
+b(elements)f(are)i(he)o(xahedra)c(\(bricks\).)581 1807
+y(4)83 b(The)20 b(elements)f(are)i(quadrilaterals.)208
+1949 y FC(num\003ag)82 b FL(Used)22 b(to)h(indicate)e(which)h
+(numbering)d(scheme)j(is)h(used)f(for)g(the)g(element)f(node)g(array)-5
+b(.)30 b Fs(num\003a)o(g)20 b FL(can)i(tak)o(e)h(the)581
+2059 y(follo)n(wing)c(tw)o(o)h(v)n(alues:)581 2202 y(0)83
+b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h(from)e(0)581
+2328 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j(assumed)e(that)i
+(starts)g(from)e(1)208 2445 y FC(dxadj,)g(dadjncy)581
+2554 y FL(These)31 b(arrays)g(store)g(the)g(adjacenc)o(y)e(structure)h
+(of)h(the)g(dual)g(graph.)56 b(The)31 b(user)g(must)g(pro)o(vide)e
+(arrays)h(that)581 2664 y(are)25 b(suf)n(\002ciently)e(lar)o(ge)h(to)g
+(store)h(the)f(graph.)37 b(The)24 b(size)h(of)g(array)e
+Fs(dxadj)h FL(is)h Fs(ne+1)f FL(where)g(the)h(size)g(of)f
+Fs(dadjncy)581 2773 y FL(depends)e(on)g(the)h(type)f(of)h(the)g(mesh.)
+33 b(F)o(or)22 b(triangular)n(-element)e(meshes,)j Fs(dadjncy)f
+FL(should)f(be)i(at)h(least)f(3)d FM(\003)h Fs(ne)o FL(,)581
+2883 y(for)i(tetrahedra-element)d(and)j(quadrilateral-element)d
+(meshes,)j Fs(dadjncy)f FL(should)g(be)i(at)f(least)h(4)d
+FM(\003)g Fs(ne)o FL(,)j(and)f(for)581 2993 y(he)o(xahedra-element)16
+b(meshes,)k Fs(dadjncy)f FL(should)g(be)h(at)h(least)g(6)d
+FM(\003)g Fs(ne)p FL(.)0 3169 y FB(Note)208 3278 y FL(The)h(dual)f
+(graph)g(is)j(de\002ned)d(as)i(the)g(graph)e(in)h(which)g(each)g(v)o
+(erte)o(x)f(of)h(the)g(graph)f(corresponds)f(to)j(an)f(element)g(in)h
+(the)f(mesh,)208 3388 y(and)g(tw)o(o)i(v)o(ertices)e(are)h(connected)f
+(by)h(an)g(edge)f(if)i(the)f(corresponding)d(elements)j(share)f(a)i(f)o
+(ace.)1908 5649 y(41)p eop
+%%Page: 42 42
+42 41 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(EstimateMemor)q(y)21
+b FL(\(int)f(*n,)f(idxtype)g(*xadj,)g(int)h(*adjnc)o(y)-5
+b(,)18 b(int)i(*num\003ag,)f(int)h(*optype,)e(int)j(*nbytes\))0
+342 y FB(Description)208 452 y FL(This)d(function)e(is)j(used)e(to)h
+(estimate)g(the)g(amount)f(of)g(memory)g(that)h(will)g(be)g(used)g(by)h
+Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r FL(.)20 b(Ev)o(en)d(though,)h
+Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)22 b FL(dynam-)208
+561 y(ically)f(allocates)g(the)g(amount)f(of)g(memory)g(that)h(it)h
+(needs,)e(this)i(function)d(can)i(be)g(useful)g(in)g(determining)e(if)i
+(the)g(amount)f(of)208 671 y(memory)e(in)i(the)h(system)f(is)h(suf)n
+(\002cient)f(for)h Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r
+FL(.)0 847 y FB(P)n(arameter)o(s)208 966 y FC(n)327 b
+FL(The)20 b(number)e(of)i(v)o(ertices)g(in)g(the)h(graph.)208
+1083 y FC(xadj,)e(adjncy)581 1193 y FL(The)h(adjacenc)o(y)e(structure)i
+(of)g(the)g(graph)f(as)i(described)d(in)j(Section)f(5.1.)208
+1335 y FC(num\003ag)82 b FL(Used)22 b(to)h(indicate)e(which)h
+(numbering)d(scheme)j(is)h(used)f(for)g(the)g(element)f(node)g(array)-5
+b(.)30 b Fs(num\003a)o(g)20 b FL(can)i(tak)o(e)h(the)581
+1445 y(follo)n(wing)c(tw)o(o)h(v)n(alues:)581 1588 y(0)83
+b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h(from)e(0)581
+1714 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j(assumed)e(that)i
+(starts)g(from)e(1)208 1857 y FC(optype)132 b FL(Indicates)15
+b(the)h(operation)d(for)i(which)g(the)h(memory)e(will)i(be)g
+(estimated.)23 b Fs(optype)14 b FL(can)i(tak)o(e)f(the)h(follo)n(wing)e
+(v)n(alues:)581 2000 y(1)83 b(Estimates)15 b(the)h(memory)d(needed)h
+(for)h Fz(METIS)p 2076 2000 V 30 w(P)m(ar)s(tGr)o(aphRecursiv)n(e)g
+FL(and)g Fz(METIS)p 3260 2000 V 30 w(WP)m(ar)s(tGr)o(aphRecursiv)n(e)p
+FL(.)581 2126 y(2)83 b(Estimates)20 b(the)h(memory)d(needed)h(for)g
+Fz(METIS)p 2100 2126 V 31 w(P)m(ar)s(tGr)o(aphKw)o(a)n(y)h
+FL(and)g Fz(METIS)p 3127 2126 V 30 w(WP)m(ar)s(tGr)o(aphKw)o(a)n(y)p
+FL(.)581 2252 y(3)83 b(Estimates)20 b(the)h(memory)d(needed)h(for)g
+Fz(METIS)p 2100 2252 V 31 w(EdgeND)p FL(.)581 2378 y(4)83
+b(Estimates)25 b(the)g(memory)d(needed)i(for)g Fz(METIS)p
+2123 2378 V 30 w(NodeND)p FL(,)i(b)n(ut)e(it)i(does)e(not)h(tak)o(e)f
+(into)h(account)e(memory)706 2488 y(sa)n(v)o(ed)d(due)f(to)i
+(compression.)208 2631 y FC(nbytes)142 b FL(Upon)19 b(return,)g
+Fs(nbytes)h FL(stores)g(an)h(estimate)f(on)g(the)g(number)e(of)i(bytes)
+g(that)j Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)24 b FL(requires.)1908
+5649 y(42)p eop
+%%Page: 43 43
+43 42 bop 0 83 a Fr(5.8)100 b(C)28 b(and)g(For)r(tran)f(Suppor)r(t)0
+242 y FL(The)g(v)n(arious)g(routines)f(in)k Fz(M)l FG(E)-17
+b Fz(T)g FG(I)p Fz(S)r(lib)31 b FL(can)c(be)h(called)f(from)g(either)g
+(C)h(or)f(F)o(ortran)g(programs.)45 b(Using)27 b(C)i(with)h
+Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)30 b FL(is)f(quite)0
+352 y(straightforw)o(ard)24 b(\(as)30 b Fz(M)l FG(E)-17
+b Fz(T)g FG(I)p Fz(S)31 b FL(is)d(written)f(entirely)f(in)h(C\).)g(Ho)n
+(we)n(v)o(er)m(,)h Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)31
+b FL(fully)26 b(supports)g(F)o(ortran)g(as)h(well.)46
+b(This)27 b(support)0 462 y(comes)20 b(in)g(three)g(forms.)104
+638 y(1.)41 b(All)20 b(the)h(scalar)f(ar)o(guments)e(in)i(the)h
+(routines)e(are)h(passed)g(by)g(reference)e(to)j(f)o(acilitate)f(F)o
+(ortran)f(programs.)104 814 y(2.)41 b(All)22 b(the)g(routines)f(tak)o
+(e)h(a)h(parameter)d(called)i Fs(num\003a)o(g)e FL(indicating)h
+(whether)g(or)h(not)f(the)h(numbering)e(of)h(the)h(graph)f(or)h(mesh)
+208 923 y(starts)28 b(from)e(0)h(or)g(1.)46 b(In)27 b(C)h(programs)e
+(numbering)e(usually)j(starts)h(from)e(0,)j(whereas)e(in)g(F)o(ortran)f
+(programs)f(numbering)208 1033 y(starts)c(from)e(1.)104
+1209 y(3.)43 b Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)21
+b FL(incorporates)c(alternati)n(v)o(e)g(names)i(for)f(each)g(of)g(the)h
+(routines)e(to)i(f)o(acilitate)g(linking)e(the)i(library)f(with)g(F)o
+(ortran)g(pro-)208 1318 y(grams.)29 b(In)22 b(particular)m(,)f(for)g(e)
+n(v)o(ery)g(function)h Fz(M)l FG(E)-17 b Fz(T)g FG(I)p
+Fz(S)r(lib)25 b FL(pro)o(vides)c(three)g(additional)g(names,)h(one)f
+(all)i(capital,)f(one)f(all)i(lo)n(wer)208 1428 y(case,)f(and)g(one)f
+(all)i(lo)n(wer)e(case)h(with)h(`)p 1363 1428 25 4 v
+29 w(')f(appended)e(to)i(it.)31 b(F)o(or)22 b(e)o(xample,)e(for)i
+Fz(METIS)p 2801 1428 V 30 w(P)m(ar)s(tGr)o(aphKw)o(a)n(y)p
+FL(,)i Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)26
+b FL(pro-)208 1538 y(vides)c Fz(METIS)p 664 1538 V 30
+w(P)-10 b(AR)n(TGRAPHKW)l(A)i(Y)p FL(,)24 b Fz(metis)p
+1672 1538 V 30 w(par)s(tg)o(r)o(aphkw)o(a)n(y)p FL(,)f(and)e
+Fz(metis)p 2629 1538 V 31 w(par)s(tg)o(r)o(aphkw)o(a)n(y)p
+3203 1538 V 29 w FL(.)31 b(These)22 b(e)o(xtra)g(names)208
+1647 y(allo)n(w)j(the)h(library)f(to)h(be)g(directly)f(link)o(ed)g
+(into)g(F)o(ortran)g(programs)f(on)h(a)i(wide)e(range)g(of)h
+(architectures)e(including)g(Cray)-5 b(,)208 1757 y(SGI,)20
+b(and)h(HP)-9 b(.)21 b(If)f(you)g(still)i(encounter)d(problems)g
+(linking)h(with)h(the)g(library)f(let)h(us)g(kno)n(w)f(so)h(we)g(can)g
+(include)f(appropriate)208 1866 y(support.)1908 5649
+y(43)p eop
+%%Page: 44 44
+44 43 bop 0 85 a FD(6)116 b(System)31 b(Requirements)g(and)h(Contact)f
+(Inf)n(ormation)0 261 y FL(The)24 b(distrib)n(ution)g(of)i
+Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)30 b FL(contains)24
+b(a)h(number)e(of)h(\002les,)j(that)e(total)g(to)g(o)o(v)o(er)e(22,000)
+g(lines)i(of)f(code.)38 b(It)25 b(is)h(written)e(entirely)g(in)0
+370 y(ANSI)f(C,)h(and)e(is)i(portable)e(on)g(most)h(Unix)g(systems)g
+(that)g(ha)n(v)o(e)f(an)h(ANSI)g(C)h(compiler)e(\(the)g(GNU)i(C)g
+(compiler)d(will)j(do\).)32 b(It)23 b(has)0 480 y(been)17
+b(e)o(xtensi)n(v)o(ely)g(tested)h(on)g(AIX,)g(SunOS,)f(Solaris,)i
+(IRIX,)f(Linux,)f(HP-UX,)h(BSD,)h(and)f(Unicos.)24 b(Instructions)16
+b(on)i(ho)n(w)g(to)g(b)n(uild)0 590 y(and)i(install)i
+Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)25 b FL(can)20 b(be)g(found)e(in)j
+(the)f(\002le)h Fp(INSTALL)e FL(of)h(the)g(distrib)n(ution.)100
+699 y(Ev)o(en)d(though,)i Fz(M)l FG(E)-17 b Fz(T)g FG(I)p
+Fz(S)23 b FL(contains)18 b(no)h(kno)n(wn)e(b)n(ugs,)h(it)i(does)e(not)h
+(mean)f(that)h(all)g(of)f(its)i(b)n(ugs)f(ha)n(v)o(e)f(been)g(found)f
+(and)h(\002x)o(ed.)24 b(If)18 b(you)0 809 y(\002nd)24
+b(an)o(y)f(problems,)g(please)h(send)f(email)h(to)g Fs
+(metis@cs.umn.edu)p FL(,)g(with)g(a)g(brief)f(description)g(of)g(the)h
+(problem)e(you)h(ha)n(v)o(e)h(found.)0 918 y(Also,)c(an)o(y)g(future)f
+(updates)g(to)j Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)25
+b FL(will)c(be)f(made)g(a)n(v)n(ailable)f(on)h(WWW)i(at)f
+Fs(http://www)-6 b(.cs.umn.edu/\230metis)p FL(.)0 1164
+y FD(Ref)o(erences)37 1331 y FK([1])42 b(Stephen)26 b(T)-6
+b(.)26 b(Barnard)g(and)g(Horst)g(D.)f(Simon.)49 b(A)25
+b(f)o(ast)h(multile)n(v)o(el)g(implementation)g(of)g(recursi)n(v)o(e)g
+(spectral)g(bisection)h(for)e(partitioning)166 1431 y(unstructured)d
+(problems.)34 b(In)21 b FJ(Pr)m(oceedings)h(of)e(the)h(sixth)g(SIAM)g
+(confer)m(ence)i(on)e(P)-6 b(ar)o(allel)20 b(Pr)m(ocessing)i(for)e
+(Scienti\002c)i(Computing)p FK(,)g(pages)166 1532 y(711\226718,)f
+(1993.)37 1649 y([2])42 b(A.)19 b(Geor)o(ge)h(and)h(J.)e(W)-7
+b(.-H.)18 b(Liu.)29 b FJ(Computer)21 b(Solution)f(of)g(Lar)m(g)o(e)h
+(Spar)o(se)g(P)-6 b(ositive)19 b(De\002nite)h(Systems)p
+FK(.)30 b(Prentice-Hall,)19 b(Engle)n(w)o(ood)i(Clif)n(fs,)166
+1749 y(NJ,)d(1981.)37 1866 y([3])42 b(Anshul)d(Gupta,)44
+b(Geor)o(ge)39 b(Karypis,)44 b(and)c(V)l(ipin)e(K)o(umar)l(.)91
+b(Highly)39 b(scalable)g(parallel)g(algorithms)g(for)g(sparse)g(matrix)
+f(f)o(actoriza-)166 1967 y(tion.)64 b FJ(IEEE)30 b(T)l(r)o(ansactions)h
+(on)g(P)-6 b(ar)o(allel)30 b(and)i(Distrib)o(uted)e(Systems)p
+FK(,)k(8\(5\):502\226520,)i(May)31 b(1997.)66 b(A)-6
+b(v)n(ailable)31 b(on)g(WWW)e(at)i(URL)166 2067 y(http://www)-5
+b(.cs.umn.edu/\230karypis.)37 2184 y([4])42 b(Bruce)15
+b(Hendrickson)i(and)f(Robert)f(Leland.)k(The)c(chaco)h(user')l(s)f
+(guide,)h(v)o(ersion)g(1.0.)i(T)-5 b(echnical)16 b(Report)f
+(SAND93-2339,)h(Sandia)g(National)166 2285 y(Laboratories,)j(1993.)37
+2402 y([5])42 b(Bruce)26 b(Hendrickson)h(and)f(Robert)g(Leland.)48
+b(A)25 b(multile)n(v)o(el)g(algorithm)h(for)g(partitioning)g(graphs.)49
+b(T)-5 b(echnical)25 b(Report)h(SAND93-1301,)166 2502
+y(Sandia)19 b(National)g(Laboratories,)g(1993.)37 2619
+y([6])42 b(G.)30 b(Karypis)g(and)h(V)-10 b(.)30 b(K)o(umar)l(.)62
+b(Multile)n(v)o(el)31 b(algorithms)f(for)g(multi-constraint)g(graph)i
+(partitioning.)63 b(T)-5 b(echnical)30 b(Report)g(TR)g(98-019,)166
+2720 y(Department)19 b(of)g(Computer)h(Science,)f(Uni)n(v)o(ersity)g
+(of)g(Minnesota,)h(1998.)37 2837 y([7])42 b(G.)24 b(Karypis)h(and)g(V)
+-10 b(.)24 b(K)o(umar)l(.)44 b(Multile)n(v)o(el)25 b(k-w)o(ay)g
+(partitioning)g(scheme)g(for)f(irre)o(gular)g(graphs.)46
+b FJ(J)n(ournal)26 b(of)e(P)-6 b(ar)o(allel)24 b(and)h(Distrib)o(uted)
+166 2937 y(Computing)p FK(,)19 b(48\(1\):96\226129,)j(1998.)28
+b(Also)18 b(a)o(v)n(ailable)i(on)f(WWW)e(at)i(URL)f(http://www)-5
+b(.cs.umn.edu/\230karypis.)37 3055 y([8])42 b(G.)23 b(Karypis)h(and)g
+(V)-10 b(.)23 b(K)o(umar)l(.)42 b(A)23 b(f)o(ast)h(and)g(highly)g
+(quality)g(multile)n(v)o(el)f(scheme)i(for)e(partitioning)h(irre)o
+(gular)f(graphs.)43 b FJ(SIAM)23 b(J)n(ournal)i(on)166
+3155 y(Scienti\002c)f(Computing)p FK(,)g(1998)g(\(to)f(appear\).)40
+b(Also)23 b(a)o(v)n(ailable)g(on)h(WWW)d(at)i(URL)f(http://www)-5
+b(.cs.umn.edu/\230karypis.)23 b(A)g(short)g(v)o(ersion)166
+3255 y(appears)d(in)f(Intl.)f(Conf.)h(on)g(P)o(arallel)f(Processing)h
+(1995.)37 3372 y([9])42 b(Geor)o(ge)21 b(Karypis,)f(Rajat)g(Aggarw)o
+(al,)h(V)l(ipin)f(K)o(umar)m(,)g(and)i(Shashi)e(Shekhar)l(.)32
+b(Multile)n(v)o(el)20 b(hyper)o(graph)i(partitioning:)27
+b(Application)21 b(in)f(vlsi)166 3473 y(domain.)28 b(In)19
+b FJ(Pr)m(oceedings)g(of)g(the)g(Design)h(and)f(A)o(utomation)g(Confer)
+m(ence)p FK(,)h(1997.)0 3590 y([10])42 b(V)l(ipin)19
+b(K)o(umar)m(,)h(Ananth)g(Grama,)f(Anshul)i(Gupta,)e(and)i(Geor)o(ge)e
+(Karypis.)30 b FJ(Intr)m(oduction)20 b(to)g(P)-6 b(ar)o(allel)19
+b(Computing:)25 b(Design)20 b(and)h(Analysis)166 3690
+y(of)e(Algorithms)p FK(.)27 b(Benjamin/Cummings)20 b(Publishing)f
+(Compan)o(y)-5 b(,)20 b(Redw)o(ood)g(City)-5 b(,)19 b(CA,)f(1994.)1908
+5649 y FL(44)p eop
+%%Trailer
+end
+userdict /end-hook known{end-hook}if
+%%EOF
diff --git a/Metis/balance.c b/Metis/balance.c
new file mode 100644
index 0000000000..b5fc3d50ea
--- /dev/null
+++ b/Metis/balance.c
@@ -0,0 +1,278 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * balance.c
+ *
+ * This file contains code that is used to forcefully balance either
+ * bisections or k-sections
+ *
+ * Started 7/29/97
+ * George
+ *
+ * $Id: balance.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+/*************************************************************************
+* This function is the entry point of the bisection balancing algorithms.
+**************************************************************************/
+void Balance2Way(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor)
+{
+  int i, j, nvtxs, from, imax, gain, mindiff;
+  idxtype *id, *ed;
+
+  /* Return right away if the balance is OK */
+  mindiff = abs(tpwgts[0]-graph->pwgts[0]);
+  if (mindiff < 3*(graph->pwgts[0]+graph->pwgts[1])/graph->nvtxs)
+    return;
+  if (graph->pwgts[0] > tpwgts[0] && graph->pwgts[0] < (int)(ubfactor*tpwgts[0]))
+    return;
+  if (graph->pwgts[1] > tpwgts[1] && graph->pwgts[1] < (int)(ubfactor*tpwgts[1]))
+    return;
+
+  if (graph->nbnd > 0)
+    Bnd2WayBalance(ctrl, graph, tpwgts);
+  else
+    General2WayBalance(ctrl, graph, tpwgts);
+
+}
+
+
+
+/*************************************************************************
+* This function balances two partitions by moving boundary nodes
+* from the domain that is overweight to the one that is underweight.
+**************************************************************************/
+void Bnd2WayBalance(CtrlType *ctrl, GraphType *graph, int *tpwgts)
+{
+  int i, ii, j, k, kwgt, nvtxs, nbnd, nswaps, from, to, pass, me, tmp;
+  idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind, *pwgts;
+  idxtype *moved, *perm;
+  PQueueType parts;
+  int higain, oldgain, mincut, mindiff;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  vwgt = graph->vwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+  where = graph->where;
+  id = graph->id;
+  ed = graph->ed;
+  pwgts = graph->pwgts;
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+
+  moved = idxwspacemalloc(ctrl, nvtxs);
+  perm = idxwspacemalloc(ctrl, nvtxs);
+
+  /* Determine from which domain you will be moving data */
+  mindiff = abs(tpwgts[0]-pwgts[0]);
+  from = (pwgts[0] < tpwgts[0] ? 1 : 0);
+  to = (from+1)%2;
+
+  IFSET(ctrl->dbglvl, DBG_REFINE, 
+     printf("Partitions: [%6d %6d] T[%6d %6d], Nv-Nb[%6d %6d]. ICut: %6d [B]\n",
+             pwgts[0], pwgts[1], tpwgts[0], tpwgts[1], graph->nvtxs, graph->nbnd, graph->mincut));
+
+  tmp = graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)];
+  PQueueInit(ctrl, &parts, nvtxs, tmp);
+
+  idxset(nvtxs, -1, moved);
+
+  ASSERT(ComputeCut(graph, where) == graph->mincut);
+  ASSERT(CheckBnd(graph));
+
+  /* Insert the boundary nodes of the proper partition whose size is OK in the priority queue */
+  nbnd = graph->nbnd;
+  RandomPermute(nbnd, perm, 1);
+  for (ii=0; ii<nbnd; ii++) {
+    i = perm[ii];
+    ASSERT(ed[bndind[i]] > 0 || id[bndind[i]] == 0);
+    ASSERT(bndptr[bndind[i]] != -1);
+    if (where[bndind[i]] == from && vwgt[bndind[i]] <= mindiff)
+      PQueueInsert(&parts, bndind[i], ed[bndind[i]]-id[bndind[i]]);
+  }
+
+  mincut = graph->mincut;
+  for (nswaps=0; nswaps<nvtxs; nswaps++) {
+    if ((higain = PQueueGetMax(&parts)) == -1)
+      break;
+    ASSERT(bndptr[higain] != -1);
+
+    if (pwgts[to]+vwgt[higain] > tpwgts[to])
+      break;
+
+    mincut -= (ed[higain]-id[higain]);
+    INC_DEC(pwgts[to], pwgts[from], vwgt[higain]);
+
+    where[higain] = to;
+    moved[higain] = nswaps;
+
+    IFSET(ctrl->dbglvl, DBG_MOVEINFO, 
+      printf("Moved %6d from %d. [%3d %3d] %5d [%4d %4d]\n", higain, from, ed[higain]-id[higain], vwgt[higain], mincut, pwgts[0], pwgts[1]));
+
+    /**************************************************************
+    * Update the id[i]/ed[i] values of the affected nodes
+    ***************************************************************/
+    SWAP(id[higain], ed[higain], tmp);
+    if (ed[higain] == 0 && xadj[higain] < xadj[higain+1]) 
+      BNDDelete(nbnd, bndind,  bndptr, higain);
+
+    for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+      k = adjncy[j];
+      oldgain = ed[k]-id[k];
+
+      kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
+      INC_DEC(id[k], ed[k], kwgt);
+
+      /* Update its boundary information and queue position */
+      if (bndptr[k] != -1) { /* If k was a boundary vertex */
+        if (ed[k] == 0) { /* Not a boundary vertex any more */
+          BNDDelete(nbnd, bndind, bndptr, k);
+          if (moved[k] == -1 && where[k] == from && vwgt[k] <= mindiff)  /* Remove it if in the queues */
+            PQueueDelete(&parts, k, oldgain);
+        }
+        else { /* If it has not been moved, update its position in the queue */
+          if (moved[k] == -1 && where[k] == from && vwgt[k] <= mindiff)
+            PQueueUpdate(&parts, k, oldgain, ed[k]-id[k]);
+        }
+      }
+      else {
+        if (ed[k] > 0) {  /* It will now become a boundary vertex */
+          BNDInsert(nbnd, bndind, bndptr, k);
+          if (moved[k] == -1 && where[k] == from && vwgt[k] <= mindiff) 
+            PQueueInsert(&parts, k, ed[k]-id[k]);
+        }
+      }
+    }
+  }
+
+  IFSET(ctrl->dbglvl, DBG_REFINE, 
+    printf("\tMinimum cut: %6d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, pwgts[0], pwgts[1], nbnd));
+
+  graph->mincut = mincut;
+  graph->nbnd = nbnd;
+
+  PQueueFree(ctrl, &parts);
+
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+/*************************************************************************
+* This function balances two partitions by moving the highest gain 
+* (including negative gain) vertices to the other domain.
+* It is used only when tha unbalance is due to non contigous
+* subdomains. That is, the are no boundary vertices.
+* It moves vertices from the domain that is overweight to the one that 
+* is underweight.
+**************************************************************************/
+void General2WayBalance(CtrlType *ctrl, GraphType *graph, int *tpwgts)
+{
+  int i, ii, j, k, kwgt, nvtxs, nbnd, nswaps, from, to, pass, me, tmp;
+  idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind, *pwgts;
+  idxtype *moved, *perm;
+  PQueueType parts;
+  int higain, oldgain, mincut, mindiff;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  vwgt = graph->vwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+  where = graph->where;
+  id = graph->id;
+  ed = graph->ed;
+  pwgts = graph->pwgts;
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+
+  moved = idxwspacemalloc(ctrl, nvtxs);
+  perm = idxwspacemalloc(ctrl, nvtxs);
+
+  /* Determine from which domain you will be moving data */
+  mindiff = abs(tpwgts[0]-pwgts[0]);
+  from = (pwgts[0] < tpwgts[0] ? 1 : 0);
+  to = (from+1)%2;
+
+  IFSET(ctrl->dbglvl, DBG_REFINE, 
+     printf("Partitions: [%6d %6d] T[%6d %6d], Nv-Nb[%6d %6d]. ICut: %6d [B]\n",
+             pwgts[0], pwgts[1], tpwgts[0], tpwgts[1], graph->nvtxs, graph->nbnd, graph->mincut));
+
+  tmp = graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)];
+  PQueueInit(ctrl, &parts, nvtxs, tmp);
+
+  idxset(nvtxs, -1, moved);
+
+  ASSERT(ComputeCut(graph, where) == graph->mincut);
+  ASSERT(CheckBnd(graph));
+
+  /* Insert the nodes of the proper partition whose size is OK in the priority queue */
+  RandomPermute(nvtxs, perm, 1);
+  for (ii=0; ii<nvtxs; ii++) {
+    i = perm[ii];
+    if (where[i] == from && vwgt[i] <= mindiff)
+      PQueueInsert(&parts, i, ed[i]-id[i]);
+  }
+
+  mincut = graph->mincut;
+  nbnd = graph->nbnd;
+  for (nswaps=0; nswaps<nvtxs; nswaps++) {
+    if ((higain = PQueueGetMax(&parts)) == -1)
+      break;
+
+    if (pwgts[to]+vwgt[higain] > tpwgts[to])
+      break;
+
+    mincut -= (ed[higain]-id[higain]);
+    INC_DEC(pwgts[to], pwgts[from], vwgt[higain]);
+
+    where[higain] = to;
+    moved[higain] = nswaps;
+
+    IFSET(ctrl->dbglvl, DBG_MOVEINFO, 
+      printf("Moved %6d from %d. [%3d %3d] %5d [%4d %4d]\n", higain, from, ed[higain]-id[higain], vwgt[higain], mincut, pwgts[0], pwgts[1]));
+
+    /**************************************************************
+    * Update the id[i]/ed[i] values of the affected nodes
+    ***************************************************************/
+    SWAP(id[higain], ed[higain], tmp);
+    if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) 
+      BNDDelete(nbnd, bndind,  bndptr, higain);
+    if (ed[higain] > 0 && bndptr[higain] == -1)
+      BNDInsert(nbnd, bndind,  bndptr, higain);
+
+    for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+      k = adjncy[j];
+      oldgain = ed[k]-id[k];
+
+      kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
+      INC_DEC(id[k], ed[k], kwgt);
+
+      /* Update the queue position */
+      if (moved[k] == -1 && where[k] == from && vwgt[k] <= mindiff)
+        PQueueUpdate(&parts, k, oldgain, ed[k]-id[k]);
+
+      /* Update its boundary information */
+      if (ed[k] == 0 && bndptr[k] != -1) 
+        BNDDelete(nbnd, bndind, bndptr, k);
+      else if (ed[k] > 0 && bndptr[k] == -1)  
+        BNDInsert(nbnd, bndind, bndptr, k);
+    }
+  }
+
+  IFSET(ctrl->dbglvl, DBG_REFINE, 
+    printf("\tMinimum cut: %6d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, pwgts[0], pwgts[1], nbnd));
+
+  graph->mincut = mincut;
+  graph->nbnd = nbnd;
+
+  PQueueFree(ctrl, &parts);
+
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+}
diff --git a/Metis/bucketsort.c b/Metis/bucketsort.c
new file mode 100644
index 0000000000..8f44b66bb9
--- /dev/null
+++ b/Metis/bucketsort.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * bucketsort.c
+ *
+ * This file contains code that implement a variety of counting sorting
+ * algorithms
+ *
+ * Started 7/25/97
+ * George
+ *
+ * $Id: bucketsort.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+
+/*************************************************************************
+* This function uses simple counting sort to return a permutation array
+* corresponding to the sorted order. The keys are assumed to start from
+* 0 and they are positive.  This sorting is used during matching.
+**************************************************************************/
+void BucketSortKeysInc(int n, int max, idxtype *keys, idxtype *tperm, idxtype *perm)
+{
+  int i, ii;
+  idxtype *counts;
+
+  counts = idxsmalloc(max+2, 0, "BucketSortKeysInc: counts");
+
+  for (i=0; i<n; i++)
+    counts[keys[i]]++;
+  MAKECSR(i, max+1, counts);
+
+  for (ii=0; ii<n; ii++) {
+    i = tperm[ii];
+    perm[counts[keys[i]]++] = i;
+  }
+
+  free(counts);
+}
+
diff --git a/Metis/ccgraph.c b/Metis/ccgraph.c
new file mode 100644
index 0000000000..b1def86912
--- /dev/null
+++ b/Metis/ccgraph.c
@@ -0,0 +1,599 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * ccgraph.c
+ *
+ * This file contains the functions that create the coarse graph
+ *
+ * Started 8/11/97
+ * George
+ *
+ * $Id: ccgraph.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+
+/*************************************************************************
+* This function creates the coarser graph
+**************************************************************************/
+void CreateCoarseGraph(CtrlType *ctrl, GraphType *graph, int cnvtxs, idxtype *match, idxtype *perm)
+{
+  int i, j, jj, k, kk, l, m, istart, iend, nvtxs, nedges, ncon, cnedges, v, u, mask, dovsize;
+  idxtype *xadj, *vwgt, *vsize, *adjncy, *adjwgt, *adjwgtsum, *auxadj;
+  idxtype *cmap, *htable;
+  idxtype *cxadj, *cvwgt, *cvsize, *cadjncy, *cadjwgt, *cadjwgtsum;
+  float *nvwgt, *cnvwgt;
+  GraphType *cgraph;
+
+  dovsize = (ctrl->optype == OP_KVMETIS ? 1 : 0);
+
+  mask = HTLENGTH;
+  if (cnvtxs < 8*mask || graph->nedges/graph->nvtxs > 15) { 
+    CreateCoarseGraphNoMask(ctrl, graph, cnvtxs, match, perm);
+    return;
+  }
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ContractTmr));
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  xadj = graph->xadj;
+  vwgt = graph->vwgt;
+  vsize = graph->vsize;
+  nvwgt = graph->nvwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+  adjwgtsum = graph->adjwgtsum;
+  cmap = graph->cmap;
+
+  /* Initialize the coarser graph */
+  cgraph = SetUpCoarseGraph(graph, cnvtxs, dovsize);
+  cxadj = cgraph->xadj;
+  cvwgt = cgraph->vwgt;
+  cvsize = cgraph->vsize;
+  cnvwgt = cgraph->nvwgt;
+  cadjwgtsum = cgraph->adjwgtsum;
+  cadjncy = cgraph->adjncy;
+  cadjwgt = cgraph->adjwgt;
+
+
+  iend = xadj[nvtxs];
+  auxadj = ctrl->wspace.auxcore; 
+  memcpy(auxadj, adjncy, iend*sizeof(idxtype)); 
+  for (i=0; i<iend; i++)
+    auxadj[i] = cmap[auxadj[i]];
+
+  htable = idxset(mask+1, -1, idxwspacemalloc(ctrl, mask+1)); 
+
+  cxadj[0] = cnvtxs = cnedges = 0;
+  for (i=0; i<nvtxs; i++) {
+    v = perm[i];
+    if (cmap[v] != cnvtxs) 
+      continue;
+
+    u = match[v];
+    if (ncon == 1)
+      cvwgt[cnvtxs] = vwgt[v];
+    else
+      scopy(ncon, nvwgt+v*ncon, cnvwgt+cnvtxs*ncon);
+
+    if (dovsize)
+      cvsize[cnvtxs] = vsize[v];
+
+    cadjwgtsum[cnvtxs] = adjwgtsum[v];
+    nedges = 0;
+
+    istart = xadj[v];
+    iend = xadj[v+1];
+    for (j=istart; j<iend; j++) {
+      k = auxadj[j];
+      kk = k&mask;
+      if ((m = htable[kk]) == -1) {
+        cadjncy[nedges] = k;
+        cadjwgt[nedges] = adjwgt[j];
+        htable[kk] = nedges++;
+      }
+      else if (cadjncy[m] == k) {
+        cadjwgt[m] += adjwgt[j];
+      }
+      else {
+        for (jj=0; jj<nedges; jj++) {
+          if (cadjncy[jj] == k) {
+            cadjwgt[jj] += adjwgt[j];
+            break;
+          }
+        }
+        if (jj == nedges) {
+          cadjncy[nedges] = k;
+          cadjwgt[nedges++] = adjwgt[j];
+        }
+      }
+    }
+
+    if (v != u) { 
+      if (ncon == 1)
+        cvwgt[cnvtxs] += vwgt[u];
+      else
+        saxpy(ncon, 1.0, nvwgt+u*ncon, 1, cnvwgt+cnvtxs*ncon, 1);
+
+      if (dovsize)
+        cvsize[cnvtxs] += vsize[u];
+
+      cadjwgtsum[cnvtxs] += adjwgtsum[u];
+
+      istart = xadj[u];
+      iend = xadj[u+1];
+      for (j=istart; j<iend; j++) {
+        k = auxadj[j];
+        kk = k&mask;
+        if ((m = htable[kk]) == -1) {
+          cadjncy[nedges] = k;
+          cadjwgt[nedges] = adjwgt[j];
+          htable[kk] = nedges++;
+        }
+        else if (cadjncy[m] == k) {
+          cadjwgt[m] += adjwgt[j];
+        }
+        else {
+          for (jj=0; jj<nedges; jj++) {
+            if (cadjncy[jj] == k) {
+              cadjwgt[jj] += adjwgt[j];
+              break;
+            }
+          }
+          if (jj == nedges) {
+            cadjncy[nedges] = k;
+            cadjwgt[nedges++] = adjwgt[j];
+          }
+        }
+      }
+
+      /* Remove the contracted adjacency weight */
+      jj = htable[cnvtxs&mask];
+      if (jj >= 0 && cadjncy[jj] != cnvtxs) {
+        for (jj=0; jj<nedges; jj++) {
+          if (cadjncy[jj] == cnvtxs) 
+            break;
+        }
+      }
+      if (jj >= 0 && cadjncy[jj] == cnvtxs) { /* This 2nd check is needed for non-adjacent matchings */
+        cadjwgtsum[cnvtxs] -= cadjwgt[jj];
+        cadjncy[jj] = cadjncy[--nedges];
+        cadjwgt[jj] = cadjwgt[nedges];
+      }
+    }
+
+    ASSERTP(cadjwgtsum[cnvtxs] == idxsum(nedges, cadjwgt), ("%d %d %d %d %d\n", cnvtxs, cadjwgtsum[cnvtxs], idxsum(nedges, cadjwgt), adjwgtsum[u], adjwgtsum[v]));
+
+    for (j=0; j<nedges; j++)
+      htable[cadjncy[j]&mask] = -1;  /* Zero out the htable */
+    htable[cnvtxs&mask] = -1;
+
+    cnedges += nedges;
+    cxadj[++cnvtxs] = cnedges;
+    cadjncy += nedges;
+    cadjwgt += nedges;
+  }
+
+  cgraph->nedges = cnedges;
+
+  ReAdjustMemory(graph, cgraph, dovsize);
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ContractTmr));
+
+  idxwspacefree(ctrl, mask+1);
+
+}
+
+
+/*************************************************************************
+* This function creates the coarser graph
+**************************************************************************/
+void CreateCoarseGraphNoMask(CtrlType *ctrl, GraphType *graph, int cnvtxs, idxtype *match, idxtype *perm)
+{
+  int i, j, k, m, istart, iend, nvtxs, nedges, ncon, cnedges, v, u, dovsize;
+  idxtype *xadj, *vwgt, *vsize, *adjncy, *adjwgt, *adjwgtsum, *auxadj;
+  idxtype *cmap, *htable;
+  idxtype *cxadj, *cvwgt, *cvsize, *cadjncy, *cadjwgt, *cadjwgtsum;
+  float *nvwgt, *cnvwgt;
+  GraphType *cgraph;
+
+  dovsize = (ctrl->optype == OP_KVMETIS ? 1 : 0);
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ContractTmr));
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  xadj = graph->xadj;
+  vwgt = graph->vwgt;
+  vsize = graph->vsize;
+  nvwgt = graph->nvwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+  adjwgtsum = graph->adjwgtsum;
+  cmap = graph->cmap;
+
+
+  /* Initialize the coarser graph */
+  cgraph = SetUpCoarseGraph(graph, cnvtxs, dovsize);
+  cxadj = cgraph->xadj;
+  cvwgt = cgraph->vwgt;
+  cvsize = cgraph->vsize;
+  cnvwgt = cgraph->nvwgt;
+  cadjwgtsum = cgraph->adjwgtsum;
+  cadjncy = cgraph->adjncy;
+  cadjwgt = cgraph->adjwgt;
+
+
+  htable = idxset(cnvtxs, -1, idxwspacemalloc(ctrl, cnvtxs));
+
+  iend = xadj[nvtxs];
+  auxadj = ctrl->wspace.auxcore; 
+  memcpy(auxadj, adjncy, iend*sizeof(idxtype)); 
+  for (i=0; i<iend; i++)
+    auxadj[i] = cmap[auxadj[i]];
+
+  cxadj[0] = cnvtxs = cnedges = 0;
+  for (i=0; i<nvtxs; i++) {
+    v = perm[i];
+    if (cmap[v] != cnvtxs) 
+      continue;
+
+    u = match[v];
+    if (ncon == 1)
+      cvwgt[cnvtxs] = vwgt[v];
+    else
+      scopy(ncon, nvwgt+v*ncon, cnvwgt+cnvtxs*ncon);
+
+    if (dovsize)
+      cvsize[cnvtxs] = vsize[v];
+
+    cadjwgtsum[cnvtxs] = adjwgtsum[v];
+    nedges = 0;
+
+    istart = xadj[v];
+    iend = xadj[v+1];
+    for (j=istart; j<iend; j++) {
+      k = auxadj[j];
+      if ((m = htable[k]) == -1) {
+        cadjncy[nedges] = k;
+        cadjwgt[nedges] = adjwgt[j];
+        htable[k] = nedges++;
+      }
+      else {
+        cadjwgt[m] += adjwgt[j];
+      }
+    }
+
+    if (v != u) { 
+      if (ncon == 1)
+        cvwgt[cnvtxs] += vwgt[u];
+      else
+        saxpy(ncon, 1.0, nvwgt+u*ncon, 1, cnvwgt+cnvtxs*ncon, 1);
+
+      if (dovsize)
+        cvsize[cnvtxs] += vsize[u];
+
+      cadjwgtsum[cnvtxs] += adjwgtsum[u];
+
+      istart = xadj[u];
+      iend = xadj[u+1];
+      for (j=istart; j<iend; j++) {
+        k = auxadj[j];
+        if ((m = htable[k]) == -1) {
+          cadjncy[nedges] = k;
+          cadjwgt[nedges] = adjwgt[j];
+          htable[k] = nedges++;
+        }
+        else {
+          cadjwgt[m] += adjwgt[j];
+        }
+      }
+
+      /* Remove the contracted adjacency weight */
+      if ((j = htable[cnvtxs]) != -1) {
+        ASSERT(cadjncy[j] == cnvtxs);
+        cadjwgtsum[cnvtxs] -= cadjwgt[j];
+        cadjncy[j] = cadjncy[--nedges];
+        cadjwgt[j] = cadjwgt[nedges];
+        htable[cnvtxs] = -1;
+      }
+    }
+
+    ASSERTP(cadjwgtsum[cnvtxs] == idxsum(nedges, cadjwgt), ("%d %d\n", cadjwgtsum[cnvtxs], idxsum(nedges, cadjwgt)));
+
+    for (j=0; j<nedges; j++)
+      htable[cadjncy[j]] = -1;  /* Zero out the htable */
+
+    cnedges += nedges;
+    cxadj[++cnvtxs] = cnedges;
+    cadjncy += nedges;
+    cadjwgt += nedges;
+  }
+
+  cgraph->nedges = cnedges;
+
+  ReAdjustMemory(graph, cgraph, dovsize);
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ContractTmr));
+
+  idxwspacefree(ctrl, cnvtxs);
+}
+
+
+/*************************************************************************
+* This function creates the coarser graph
+**************************************************************************/
+void CreateCoarseGraph_NVW(CtrlType *ctrl, GraphType *graph, int cnvtxs, idxtype *match, idxtype *perm)
+{
+  int i, j, jj, k, kk, l, m, istart, iend, nvtxs, nedges, ncon, cnedges, v, u, mask;
+  idxtype *xadj, *adjncy, *adjwgtsum, *auxadj;
+  idxtype *cmap, *htable;
+  idxtype *cxadj, *cvwgt, *cadjncy, *cadjwgt, *cadjwgtsum;
+  float *nvwgt, *cnvwgt;
+  GraphType *cgraph;
+
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ContractTmr));
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  xadj = graph->xadj;
+  nvwgt = graph->nvwgt;
+  adjncy = graph->adjncy;
+  adjwgtsum = graph->adjwgtsum;
+  cmap = graph->cmap;
+
+  /* Initialize the coarser graph */
+  cgraph = SetUpCoarseGraph(graph, cnvtxs, 0);
+  cxadj = cgraph->xadj;
+  cvwgt = cgraph->vwgt;
+  cnvwgt = cgraph->nvwgt;
+  cadjwgtsum = cgraph->adjwgtsum;
+  cadjncy = cgraph->adjncy;
+  cadjwgt = cgraph->adjwgt;
+
+
+  iend = xadj[nvtxs];
+  auxadj = ctrl->wspace.auxcore; 
+  memcpy(auxadj, adjncy, iend*sizeof(idxtype)); 
+  for (i=0; i<iend; i++)
+    auxadj[i] = cmap[auxadj[i]];
+
+  mask = HTLENGTH;
+  htable = idxset(mask+1, -1, idxwspacemalloc(ctrl, mask+1)); 
+
+  cxadj[0] = cnvtxs = cnedges = 0;
+  for (i=0; i<nvtxs; i++) {
+    v = perm[i];
+    if (cmap[v] != cnvtxs) 
+      continue;
+
+    u = match[v];
+    cvwgt[cnvtxs] = 1;
+    cadjwgtsum[cnvtxs] = adjwgtsum[v];
+    nedges = 0;
+
+    istart = xadj[v];
+    iend = xadj[v+1];
+    for (j=istart; j<iend; j++) {
+      k = auxadj[j];
+      kk = k&mask;
+      if ((m = htable[kk]) == -1) {
+        cadjncy[nedges] = k;
+        cadjwgt[nedges] = 1;
+        htable[kk] = nedges++;
+      }
+      else if (cadjncy[m] == k) {
+        cadjwgt[m]++;
+      }
+      else {
+        for (jj=0; jj<nedges; jj++) {
+          if (cadjncy[jj] == k) {
+            cadjwgt[jj]++;
+            break;
+          }
+        }
+        if (jj == nedges) {
+          cadjncy[nedges] = k;
+          cadjwgt[nedges++] = 1;
+        }
+      }
+    }
+
+    if (v != u) { 
+      cvwgt[cnvtxs]++;
+      cadjwgtsum[cnvtxs] += adjwgtsum[u];
+
+      istart = xadj[u];
+      iend = xadj[u+1];
+      for (j=istart; j<iend; j++) {
+        k = auxadj[j];
+        kk = k&mask;
+        if ((m = htable[kk]) == -1) {
+          cadjncy[nedges] = k;
+          cadjwgt[nedges] = 1;
+          htable[kk] = nedges++;
+        }
+        else if (cadjncy[m] == k) {
+          cadjwgt[m]++;
+        }
+        else {
+          for (jj=0; jj<nedges; jj++) {
+            if (cadjncy[jj] == k) {
+              cadjwgt[jj]++;
+              break;
+            }
+          }
+          if (jj == nedges) {
+            cadjncy[nedges] = k;
+            cadjwgt[nedges++] = 1;
+          }
+        }
+      }
+
+      /* Remove the contracted adjacency weight */
+      jj = htable[cnvtxs&mask];
+      if (jj >= 0 && cadjncy[jj] != cnvtxs) {
+        for (jj=0; jj<nedges; jj++) {
+          if (cadjncy[jj] == cnvtxs) 
+            break;
+        }
+      }
+      if (jj >= 0 && cadjncy[jj] == cnvtxs) { /* This 2nd check is needed for non-adjacent matchings */
+        cadjwgtsum[cnvtxs] -= cadjwgt[jj];
+        cadjncy[jj] = cadjncy[--nedges];
+        cadjwgt[jj] = cadjwgt[nedges];
+      }
+    }
+
+    ASSERTP(cadjwgtsum[cnvtxs] == idxsum(nedges, cadjwgt), ("%d %d %d %d %d\n", cnvtxs, cadjwgtsum[cnvtxs], idxsum(nedges, cadjwgt), adjwgtsum[u], adjwgtsum[v]));
+
+    for (j=0; j<nedges; j++)
+      htable[cadjncy[j]&mask] = -1;  /* Zero out the htable */
+    htable[cnvtxs&mask] = -1;
+
+    cnedges += nedges;
+    cxadj[++cnvtxs] = cnedges;
+    cadjncy += nedges;
+    cadjwgt += nedges;
+  }
+
+  cgraph->nedges = cnedges;
+
+  ReAdjustMemory(graph, cgraph, 0);
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ContractTmr));
+
+  idxwspacefree(ctrl, mask+1);
+
+}
+
+
+/*************************************************************************
+* Setup the various arrays for the coarse graph
+**************************************************************************/
+GraphType *SetUpCoarseGraph(GraphType *graph, int cnvtxs, int dovsize)
+{
+  GraphType *cgraph;
+
+  cgraph = CreateGraph();
+  cgraph->nvtxs = cnvtxs;
+  cgraph->ncon = graph->ncon;
+
+  cgraph->finer = graph;
+  graph->coarser = cgraph;
+
+
+  /* Allocate memory for the coarser graph */
+  if (graph->ncon == 1) {
+    if (dovsize) {
+      cgraph->gdata = idxmalloc(5*cnvtxs+1 + 2*graph->nedges, "SetUpCoarseGraph: gdata");
+      cgraph->xadj 		= cgraph->gdata;
+      cgraph->vwgt 		= cgraph->gdata + cnvtxs+1;
+      cgraph->vsize 		= cgraph->gdata + 2*cnvtxs+1;
+      cgraph->adjwgtsum 	= cgraph->gdata + 3*cnvtxs+1;
+      cgraph->cmap 		= cgraph->gdata + 4*cnvtxs+1;
+      cgraph->adjncy 		= cgraph->gdata + 5*cnvtxs+1;
+      cgraph->adjwgt 		= cgraph->gdata + 5*cnvtxs+1 + graph->nedges;
+    }
+    else {
+      cgraph->gdata = idxmalloc(4*cnvtxs+1 + 2*graph->nedges, "SetUpCoarseGraph: gdata");
+      cgraph->xadj 		= cgraph->gdata;
+      cgraph->vwgt 		= cgraph->gdata + cnvtxs+1;
+      cgraph->adjwgtsum 	= cgraph->gdata + 2*cnvtxs+1;
+      cgraph->cmap 		= cgraph->gdata + 3*cnvtxs+1;
+      cgraph->adjncy 		= cgraph->gdata + 4*cnvtxs+1;
+      cgraph->adjwgt 		= cgraph->gdata + 4*cnvtxs+1 + graph->nedges;
+    }
+  }
+  else {
+    if (dovsize) {
+      cgraph->gdata = idxmalloc(4*cnvtxs+1 + 2*graph->nedges, "SetUpCoarseGraph: gdata");
+      cgraph->xadj 		= cgraph->gdata;
+      cgraph->vsize 		= cgraph->gdata + cnvtxs+1;
+      cgraph->adjwgtsum 	= cgraph->gdata + 2*cnvtxs+1;
+      cgraph->cmap 		= cgraph->gdata + 3*cnvtxs+1;
+      cgraph->adjncy 		= cgraph->gdata + 4*cnvtxs+1;
+      cgraph->adjwgt 		= cgraph->gdata + 4*cnvtxs+1 + graph->nedges;
+    }
+    else {
+      cgraph->gdata = idxmalloc(3*cnvtxs+1 + 2*graph->nedges, "SetUpCoarseGraph: gdata");
+      cgraph->xadj 		= cgraph->gdata;
+      cgraph->adjwgtsum 	= cgraph->gdata + cnvtxs+1;
+      cgraph->cmap 		= cgraph->gdata + 2*cnvtxs+1;
+      cgraph->adjncy 		= cgraph->gdata + 3*cnvtxs+1;
+      cgraph->adjwgt 		= cgraph->gdata + 3*cnvtxs+1 + graph->nedges;
+    }
+
+    cgraph->nvwgt 	= fmalloc(graph->ncon*cnvtxs, "SetUpCoarseGraph: nvwgt");
+  }
+
+  return cgraph;
+}
+
+
+/*************************************************************************
+* This function re-adjusts the amount of memory that was allocated if
+* it will lead to significant savings
+**************************************************************************/
+void ReAdjustMemory(GraphType *graph, GraphType *cgraph, int dovsize) 
+{
+
+  if (cgraph->nedges > 100000 && graph->nedges < 0.7*graph->nedges) {
+    idxcopy(cgraph->nedges, cgraph->adjwgt, cgraph->adjncy+cgraph->nedges);
+
+    if (graph->ncon == 1) {
+      if (dovsize) {
+        cgraph->gdata = realloc(cgraph->gdata, (5*cgraph->nvtxs+1 + 2*cgraph->nedges)*sizeof(idxtype));
+
+        /* Do this, in case everything was copied into new space */
+        cgraph->xadj 		= cgraph->gdata;
+        cgraph->vwgt 		= cgraph->gdata + cgraph->nvtxs+1;
+        cgraph->vsize 		= cgraph->gdata + 2*cgraph->nvtxs+1;
+        cgraph->adjwgtsum	= cgraph->gdata + 3*cgraph->nvtxs+1;
+        cgraph->cmap 		= cgraph->gdata + 4*cgraph->nvtxs+1;
+        cgraph->adjncy 		= cgraph->gdata + 5*cgraph->nvtxs+1;
+        cgraph->adjwgt 		= cgraph->gdata + 5*cgraph->nvtxs+1 + cgraph->nedges;
+      }
+      else {
+        cgraph->gdata = realloc(cgraph->gdata, (4*cgraph->nvtxs+1 + 2*cgraph->nedges)*sizeof(idxtype));
+
+        /* Do this, in case everything was copied into new space */
+        cgraph->xadj 	= cgraph->gdata;
+        cgraph->vwgt 	= cgraph->gdata + cgraph->nvtxs+1;
+        cgraph->adjwgtsum	= cgraph->gdata + 2*cgraph->nvtxs+1;
+        cgraph->cmap 	= cgraph->gdata + 3*cgraph->nvtxs+1;
+        cgraph->adjncy 	= cgraph->gdata + 4*cgraph->nvtxs+1;
+        cgraph->adjwgt 	= cgraph->gdata + 4*cgraph->nvtxs+1 + cgraph->nedges;
+      }
+    }
+    else {
+      if (dovsize) {
+        cgraph->gdata = realloc(cgraph->gdata, (4*cgraph->nvtxs+1 + 2*cgraph->nedges)*sizeof(idxtype));
+
+        /* Do this, in case everything was copied into new space */
+        cgraph->xadj 		= cgraph->gdata;
+        cgraph->vsize		= cgraph->gdata + cgraph->nvtxs+1;
+        cgraph->adjwgtsum	= cgraph->gdata + 2*cgraph->nvtxs+1;
+        cgraph->cmap 		= cgraph->gdata + 3*cgraph->nvtxs+1;
+        cgraph->adjncy 		= cgraph->gdata + 4*cgraph->nvtxs+1;
+        cgraph->adjwgt 		= cgraph->gdata + 4*cgraph->nvtxs+1 + cgraph->nedges;
+      }
+      else {
+        cgraph->gdata = realloc(cgraph->gdata, (3*cgraph->nvtxs+1 + 2*cgraph->nedges)*sizeof(idxtype));
+
+        /* Do this, in case everything was copied into new space */
+        cgraph->xadj 		= cgraph->gdata;
+        cgraph->adjwgtsum	= cgraph->gdata + cgraph->nvtxs+1;
+        cgraph->cmap 		= cgraph->gdata + 2*cgraph->nvtxs+1;
+        cgraph->adjncy 		= cgraph->gdata + 3*cgraph->nvtxs+1;
+        cgraph->adjwgt 		= cgraph->gdata + 3*cgraph->nvtxs+1 + cgraph->nedges;
+      }
+    }
+  }
+
+}
diff --git a/Metis/coarsen.c b/Metis/coarsen.c
new file mode 100644
index 0000000000..904cb28522
--- /dev/null
+++ b/Metis/coarsen.c
@@ -0,0 +1,83 @@
+/*
+ * coarsen.c
+ *
+ * This file contains the driving routines for the coarsening process 
+ *
+ * Started 7/23/97
+ * George
+ *
+ * $Id: coarsen.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function takes a graph and creates a sequence of coarser graphs
+**************************************************************************/
+GraphType *Coarsen2Way(CtrlType *ctrl, GraphType *graph)
+{
+  int clevel;
+  GraphType *cgraph;
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->CoarsenTmr));
+
+  cgraph = graph;
+
+  /* The following is ahack to allow the multiple bisections to go through with correct
+     coarsening */
+  if (ctrl->CType > 20) {
+    clevel = 1;
+    ctrl->CType -= 20;
+  }
+  else
+    clevel = 0;
+
+  do {
+    IFSET(ctrl->dbglvl, DBG_COARSEN, printf("%6d %7d [%d] [%d %d]\n",
+          cgraph->nvtxs, cgraph->nedges, ctrl->CoarsenTo, ctrl->maxvwgt, 
+          (cgraph->vwgt ? idxsum(cgraph->nvtxs, cgraph->vwgt) : cgraph->nvtxs)));
+
+    if (cgraph->adjwgt) {
+      switch (ctrl->CType) {
+        case MATCH_RM:
+          Match_RM(ctrl, cgraph);
+          break;
+        case MATCH_HEM:
+          if (clevel < 1)
+            Match_RM(ctrl, cgraph);
+          else
+            Match_HEM(ctrl, cgraph);
+          break;
+        case MATCH_SHEM:
+          if (clevel < 1)
+            Match_RM(ctrl, cgraph);
+          else
+            Match_SHEM(ctrl, cgraph);
+          break;
+        case MATCH_SHEMKWAY:
+          Match_SHEM(ctrl, cgraph);
+          break;
+        default:
+          errexit("Unknown CType: %d\n", ctrl->CType);
+      }
+    }
+    else {
+      Match_RM_NVW(ctrl, cgraph);
+    }
+
+    cgraph = cgraph->coarser;
+    clevel++;
+
+  } while (cgraph->nvtxs > ctrl->CoarsenTo && cgraph->nvtxs < COARSEN_FRACTION2*cgraph->finer->nvtxs && cgraph->nedges > cgraph->nvtxs/2); 
+
+  IFSET(ctrl->dbglvl, DBG_COARSEN, printf("%6d %7d [%d] [%d %d]\n",
+        cgraph->nvtxs, cgraph->nedges, ctrl->CoarsenTo, ctrl->maxvwgt, 
+        (cgraph->vwgt ? idxsum(cgraph->nvtxs, cgraph->vwgt) : cgraph->nvtxs)));
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->CoarsenTmr));
+
+  return cgraph;
+}
+
diff --git a/Metis/compress.c b/Metis/compress.c
new file mode 100644
index 0000000000..11ff2926c9
--- /dev/null
+++ b/Metis/compress.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * compress.c
+ *
+ * This file contains code for compressing nodes with identical adjacency
+ * structure and for prunning dense columns
+ *
+ * Started 9/17/97
+ * George
+ *
+ * $Id: compress.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ */
+
+#include <metis.h>
+
+/*************************************************************************
+* This function compresses a graph by merging identical vertices
+* The compression should lead to at least 10% reduction.
+**************************************************************************/
+void CompressGraph(CtrlType *ctrl, GraphType *graph, int nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *cptr, idxtype *cind)
+{
+  int i, ii, iii, j, jj, k, l, cnvtxs, cnedges;
+  idxtype *cxadj, *cadjncy, *cvwgt, *mark, *map;
+  KeyValueType *keys;
+
+  mark = idxsmalloc(nvtxs, -1, "CompressGraph: mark");
+  map = idxsmalloc(nvtxs, -1, "CompressGraph: map");
+  keys = (KeyValueType *)GKmalloc(nvtxs*sizeof(KeyValueType), "CompressGraph: keys");
+
+  /* Compute a key for each adjacency list */
+  for (i=0; i<nvtxs; i++) {
+    k = 0;
+    for (j=xadj[i]; j<xadj[i+1]; j++)
+      k += adjncy[j];
+    keys[i].key = k+i; /* Add the diagonal entry as well */
+    keys[i].val = i;
+  }
+
+  ikeysort(nvtxs, keys);
+
+  l = cptr[0] = 0;
+  for (cnvtxs=i=0; i<nvtxs; i++) {
+    ii = keys[i].val;
+    if (map[ii] == -1) { 
+      mark[ii] = i;  /* Add the diagonal entry */
+      for (j=xadj[ii]; j<xadj[ii+1]; j++) 
+        mark[adjncy[j]] = i;
+
+      cind[l++] = ii;
+      map[ii] = cnvtxs;
+
+      for (j=i+1; j<nvtxs; j++) {
+        iii = keys[j].val;
+
+        if (keys[i].key != keys[j].key || xadj[ii+1]-xadj[ii] != xadj[iii+1]-xadj[iii])
+          break; /* Break if keys or degrees are different */
+
+        if (map[iii] == -1) { /* Do a comparison if iii has not been mapped */ 
+          for (jj=xadj[iii]; jj<xadj[iii+1]; jj++) {
+            if (mark[adjncy[jj]] != i)
+              break;
+          }
+
+          if (jj == xadj[iii+1]) { /* Identical adjacency structure */
+            map[iii] = cnvtxs;
+            cind[l++] = iii;
+          }
+        }
+      }
+
+      cptr[++cnvtxs] = l;
+    }
+  }
+
+  /* printf("Original: %6d, Compressed: %6d\n", nvtxs, cnvtxs); */
+
+
+  InitGraph(graph);
+
+  if (cnvtxs >= COMPRESSION_FRACTION*nvtxs) {
+    graph->nvtxs = nvtxs;
+    graph->nedges = xadj[nvtxs];
+    graph->ncon = 1;
+    graph->xadj = xadj;
+    graph->adjncy = adjncy;
+
+    graph->gdata = idxmalloc(3*nvtxs+graph->nedges, "CompressGraph: gdata");
+    graph->vwgt    	= graph->gdata;
+    graph->adjwgtsum    = graph->gdata+nvtxs;
+    graph->cmap		= graph->gdata+2*nvtxs;
+    graph->adjwgt	= graph->gdata+3*nvtxs;
+
+    idxset(nvtxs, 1, graph->vwgt);
+    idxset(graph->nedges, 1, graph->adjwgt);
+    for (i=0; i<nvtxs; i++)
+      graph->adjwgtsum[i] = xadj[i+1]-xadj[i];
+
+    graph->label = idxmalloc(nvtxs, "CompressGraph: label");
+    for (i=0; i<nvtxs; i++)
+      graph->label[i] = i;
+  }
+  else { /* Ok, form the compressed graph  */
+    cnedges = 0;
+    for (i=0; i<cnvtxs; i++) {
+      ii = cind[cptr[i]];
+      cnedges += xadj[ii+1]-xadj[ii];
+    }
+
+    /* Allocate memory for the compressed graph*/
+    graph->gdata = idxmalloc(4*cnvtxs+1 + 2*cnedges, "CompressGraph: gdata");
+    cxadj = graph->xadj		= graph->gdata;
+    cvwgt = graph->vwgt         = graph->gdata + cnvtxs+1;
+    graph->adjwgtsum        	= graph->gdata + 2*cnvtxs+1;
+    graph->cmap                 = graph->gdata + 3*cnvtxs+1;
+    cadjncy = graph->adjncy     = graph->gdata + 4*cnvtxs+1;
+    graph->adjwgt            	= graph->gdata + 4*cnvtxs+1 + cnedges;
+
+    /* Now go and compress the graph */
+    idxset(nvtxs, -1, mark);
+    l = cxadj[0] = 0;
+    for (i=0; i<cnvtxs; i++) {
+      cvwgt[i] = cptr[i+1]-cptr[i];
+      mark[i] = i;  /* Remove any dioganal entries in the compressed graph */
+      for (j=cptr[i]; j<cptr[i+1]; j++) {
+        ii = cind[j];
+        for (jj=xadj[ii]; jj<xadj[ii+1]; jj++) {
+          k = map[adjncy[jj]];
+          if (mark[k] != i) 
+            cadjncy[l++] = k;
+          mark[k] = i;
+        }
+      }
+      cxadj[i+1] = l;
+    }
+
+    graph->nvtxs = cnvtxs;
+    graph->nedges = l;
+    graph->ncon = 1;
+
+    idxset(graph->nedges, 1, graph->adjwgt);
+    for (i=0; i<cnvtxs; i++)
+      graph->adjwgtsum[i] = cxadj[i+1]-cxadj[i];
+
+    graph->label = idxmalloc(cnvtxs, "CompressGraph: label");
+    for (i=0; i<cnvtxs; i++)
+      graph->label[i] = i;
+
+  }
+
+  GKfree(&keys, &map, &mark, LTERM);
+}
+
+
+
+/*************************************************************************
+* This function prunes all the vertices in a graph with degree greater 
+* than factor*average
+**************************************************************************/
+void PruneGraph(CtrlType *ctrl, GraphType *graph, int nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *iperm, float factor)
+{
+  int i, j, k, l, nlarge, pnvtxs, pnedges;
+  idxtype *pxadj, *padjncy, *padjwgt, *pvwgt;
+  idxtype *perm;
+
+  perm = idxmalloc(nvtxs, "PruneGraph: perm");
+
+  factor = factor*xadj[nvtxs]/nvtxs;
+
+  pnvtxs = pnedges = nlarge = 0;
+  for (i=0; i<nvtxs; i++) {
+    if (xadj[i+1]-xadj[i] < factor) {
+      perm[i] = pnvtxs;
+      iperm[pnvtxs++] = i;
+      pnedges += xadj[i+1]-xadj[i];
+    }
+    else {
+      perm[i] = nvtxs - ++nlarge;
+      iperm[nvtxs-nlarge] = i;
+    }
+  }
+
+  /* printf("Pruned %d vertices\n", nlarge); */
+
+  InitGraph(graph);
+
+  if (nlarge == 0) { /* No prunning */
+    graph->nvtxs = nvtxs;
+    graph->nedges = xadj[nvtxs];
+    graph->ncon = 1;
+    graph->xadj = xadj;
+    graph->adjncy = adjncy;
+
+    graph->gdata = idxmalloc(3*nvtxs+graph->nedges, "CompressGraph: gdata");
+    graph->vwgt    	= graph->gdata;
+    graph->adjwgtsum    = graph->gdata+nvtxs;
+    graph->cmap		= graph->gdata+2*nvtxs;
+    graph->adjwgt	= graph->gdata+3*nvtxs;
+
+    idxset(nvtxs, 1, graph->vwgt);
+    idxset(graph->nedges, 1, graph->adjwgt);
+    for (i=0; i<nvtxs; i++)
+      graph->adjwgtsum[i] = xadj[i+1]-xadj[i];
+
+    graph->label = idxmalloc(nvtxs, "CompressGraph: label");
+    for (i=0; i<nvtxs; i++)
+      graph->label[i] = i;
+  }
+  else { /* Prune the graph */
+    /* Allocate memory for the compressed graph*/
+    graph->gdata = idxmalloc(4*pnvtxs+1 + 2*pnedges, "PruneGraph: gdata");
+    pxadj = graph->xadj		= graph->gdata;
+    graph->vwgt         	= graph->gdata + pnvtxs+1;
+    graph->adjwgtsum        	= graph->gdata + 2*pnvtxs+1;
+    graph->cmap                 = graph->gdata + 3*pnvtxs+1;
+    padjncy = graph->adjncy     = graph->gdata + 4*pnvtxs+1;
+    graph->adjwgt            	= graph->gdata + 4*pnvtxs+1 + pnedges;
+
+    pxadj[0] = pnedges = l = 0;
+    for (i=0; i<nvtxs; i++) {
+      if (xadj[i+1]-xadj[i] < factor) {
+        for (j=xadj[i]; j<xadj[i+1]; j++) {
+          k = perm[adjncy[j]];
+          if (k < pnvtxs) 
+            padjncy[pnedges++] = k;
+        }
+        pxadj[++l] = pnedges;
+      }
+    }
+
+    graph->nvtxs = pnvtxs;
+    graph->nedges = pnedges;
+    graph->ncon = 1;
+
+    idxset(pnvtxs, 1, graph->vwgt);
+    idxset(pnedges, 1, graph->adjwgt);
+    for (i=0; i<pnvtxs; i++)
+      graph->adjwgtsum[i] = pxadj[i+1]-pxadj[i];
+
+    graph->label = idxmalloc(pnvtxs, "CompressGraph: label");
+    for (i=0; i<pnvtxs; i++)
+      graph->label[i] = i;
+  }
+
+  free(perm);
+
+}
+
+
+
+
+
+
+
+
+
diff --git a/Metis/debug.c b/Metis/debug.c
new file mode 100644
index 0000000000..17f19e31f4
--- /dev/null
+++ b/Metis/debug.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * debug.c
+ *
+ * This file contains code that performs self debuging
+ *
+ * Started 7/24/97
+ * George
+ *
+ * $Id: debug.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+/*************************************************************************
+* This function computes the cut given the graph and a where vector
+**************************************************************************/
+int ComputeCut(GraphType *graph, idxtype *where)
+{
+  int i, j, cut;
+
+  if (graph->adjwgt == NULL) {
+    for (cut=0, i=0; i<graph->nvtxs; i++) {
+      for (j=graph->xadj[i]; j<graph->xadj[i+1]; j++)
+        if (where[i] != where[graph->adjncy[j]])
+          cut++;
+    }
+  }
+  else {
+    for (cut=0, i=0; i<graph->nvtxs; i++) {
+      for (j=graph->xadj[i]; j<graph->xadj[i+1]; j++)
+        if (where[i] != where[graph->adjncy[j]])
+          cut += graph->adjwgt[j];
+    }
+  }
+
+  return cut/2;
+}
+
+
+/*************************************************************************
+* This function checks whether or not the boundary information is correct
+**************************************************************************/
+int CheckBnd(GraphType *graph) 
+{
+  int i, j, nvtxs, nbnd;
+  idxtype *xadj, *adjncy, *where, *bndptr, *bndind;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  where = graph->where;
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+
+  for (nbnd=0, i=0; i<nvtxs; i++) {
+    if (xadj[i+1]-xadj[i] == 0)
+      nbnd++;   /* Islands are considered to be boundary vertices */
+
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      if (where[i] != where[adjncy[j]]) {
+        nbnd++;
+        ASSERT(bndptr[i] != -1);
+        ASSERT(bndind[bndptr[i]] == i);
+        break;
+      }
+    }
+  }
+
+  ASSERTP(nbnd == graph->nbnd, ("%d %d\n", nbnd, graph->nbnd));
+
+  return 1;
+}
+
+
+
+/*************************************************************************
+* This function checks whether or not the boundary information is correct
+**************************************************************************/
+int CheckBnd2(GraphType *graph) 
+{
+  int i, j, nvtxs, nbnd, id, ed;
+  idxtype *xadj, *adjncy, *where, *bndptr, *bndind;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  where = graph->where;
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+
+  for (nbnd=0, i=0; i<nvtxs; i++) {
+    id = ed = 0;
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      if (where[i] != where[adjncy[j]]) 
+        ed += graph->adjwgt[j];
+      else
+        id += graph->adjwgt[j];
+    }
+    if (ed - id >= 0 && xadj[i] < xadj[i+1]) {
+      nbnd++;
+      ASSERTP(bndptr[i] != -1, ("%d %d %d\n", i, id, ed));
+      ASSERT(bndind[bndptr[i]] == i);
+    }
+  }
+
+  ASSERTP(nbnd == graph->nbnd, ("%d %d\n", nbnd, graph->nbnd));
+
+  return 1;
+}
+
+/*************************************************************************
+* This function checks whether or not the boundary information is correct
+**************************************************************************/
+int CheckNodeBnd(GraphType *graph, int onbnd) 
+{
+  int i, j, nvtxs, nbnd;
+  idxtype *xadj, *adjncy, *where, *bndptr, *bndind;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  where = graph->where;
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+
+  for (nbnd=0, i=0; i<nvtxs; i++) {
+    if (where[i] == 2) 
+      nbnd++;   
+  }
+
+  ASSERTP(nbnd == onbnd, ("%d %d\n", nbnd, onbnd));
+
+  for (i=0; i<nvtxs; i++) {
+    if (where[i] != 2) {
+      ASSERTP(bndptr[i] == -1, ("%d %d\n", i, bndptr[i]));
+    }
+    else {
+      ASSERTP(bndptr[i] != -1, ("%d %d\n", i, bndptr[i]));
+    }
+  }
+
+  return 1;
+}
+
+
+
+/*************************************************************************
+* This function checks whether or not the rinfo of a vertex is consistent
+**************************************************************************/
+int CheckRInfo(RInfoType *rinfo)
+{
+  int i, j;
+
+  for (i=0; i<rinfo->ndegrees; i++) {
+    for (j=i+1; j<rinfo->ndegrees; j++)
+      ASSERTP(rinfo->edegrees[i].pid != rinfo->edegrees[j].pid, ("%d %d %d %d\n", i, j, rinfo->edegrees[i].pid, rinfo->edegrees[j].pid));
+  }
+
+  return 1;
+}
+
+
+
+/*************************************************************************
+* This function checks the correctness of the NodeFM data structures
+**************************************************************************/
+int CheckNodePartitionParams(GraphType *graph)
+{
+  int i, j, k, l, nvtxs, me, other;
+  idxtype *xadj, *adjncy, *adjwgt, *vwgt, *where;
+  idxtype edegrees[2], pwgts[3];
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  vwgt = graph->vwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  where = graph->where;
+
+  /*------------------------------------------------------------
+  / Compute now the separator external degrees
+  /------------------------------------------------------------*/
+  pwgts[0] = pwgts[1] = pwgts[2] = 0;
+  for (i=0; i<nvtxs; i++) {
+    me = where[i];
+    pwgts[me] += vwgt[i];
+
+    if (me == 2) { /* If it is on the separator do some computations */
+      edegrees[0] = edegrees[1] = 0;
+
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        other = where[adjncy[j]];
+        if (other != 2)
+          edegrees[other] += vwgt[adjncy[j]];
+      }
+      if (edegrees[0] != graph->nrinfo[i].edegrees[0] || edegrees[1] != graph->nrinfo[i].edegrees[1]) {
+        printf("Something wrong with edegrees: %d %d %d %d %d\n", i, edegrees[0], edegrees[1], graph->nrinfo[i].edegrees[0], graph->nrinfo[i].edegrees[1]);
+        return 0;
+      }
+    }
+  }
+
+  if (pwgts[0] != graph->pwgts[0] || pwgts[1] != graph->pwgts[1] || pwgts[2] != graph->pwgts[2])
+    printf("Something wrong with part-weights: %d %d %d %d %d %d\n", pwgts[0], pwgts[1], pwgts[2], graph->pwgts[0], graph->pwgts[1], graph->pwgts[2]);
+
+  return 1;
+}
+
+
+/*************************************************************************
+* This function checks if the separator is indeed a separator
+**************************************************************************/
+int IsSeparable(GraphType *graph)
+{
+  int i, j, nvtxs, other;
+  idxtype *xadj, *adjncy, *where;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  where = graph->where;
+
+  for (i=0; i<nvtxs; i++) {
+    if (where[i] == 2)
+      continue;
+    other = (where[i]+1)%2;
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      ASSERTP(where[adjncy[j]] != other, ("%d %d %d %d %d %d\n", i, where[i], adjncy[j], where[adjncy[j]], xadj[i+1]-xadj[i], xadj[adjncy[j]+1]-xadj[adjncy[j]]));
+    }
+  }
+
+  return 1;
+}
+
+
diff --git a/Metis/defs.h b/Metis/defs.h
new file mode 100644
index 0000000000..7696998e61
--- /dev/null
+++ b/Metis/defs.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * defs.h
+ *
+ * This file contains constant definitions
+ *
+ * Started 8/27/94
+ * George
+ *
+ * $Id: defs.h,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#define METISTITLE              "  METIS 4.0.1 Copyright 1998, Regents of the University of Minnesota\n\n"
+#define MAXLINE			1280000
+
+#define LTERM			(void **) 0	/* List terminator for GKfree() */
+
+#define MAXNCON			16		/* The maximum number of constrains */
+#define MAXNOBJ			16		/* The maximum number of objectives */
+
+#define PLUS_GAINSPAN   	500             /* Parameters for FM buckets */
+#define NEG_GAINSPAN    	500
+
+#define HTLENGTH		((1<<11)-1)
+
+/* Meaning of various options[] parameters */
+#define OPTION_PTYPE		0
+#define OPTION_CTYPE		1
+#define OPTION_ITYPE		2
+#define OPTION_RTYPE		3
+#define OPTION_DBGLVL		4
+#define OPTION_OFLAGS		5
+#define OPTION_PFACTOR		6
+#define OPTION_NSEPS		7
+
+#define OFLAG_COMPRESS		1	/* Try to compress the graph */
+#define OFLAG_CCMP		2	/* Find and order connected components */
+
+
+/* Default options for PMETIS */
+#define PMETIS_CTYPE		MATCH_SHEM
+#define PMETIS_ITYPE		IPART_GGPKL
+#define PMETIS_RTYPE		RTYPE_FM
+#define PMETIS_DBGLVL		0
+
+/* Default options for KMETIS */
+#define KMETIS_CTYPE		MATCH_SHEM
+#define KMETIS_ITYPE		IPART_PMETIS
+#define KMETIS_RTYPE		RTYPE_KWAYRANDOM_MCONN
+#define KMETIS_DBGLVL		0
+
+/* Default options for OEMETIS */
+#define OEMETIS_CTYPE		MATCH_SHEM
+#define OEMETIS_ITYPE		IPART_GGPKL
+#define OEMETIS_RTYPE		RTYPE_FM
+#define OEMETIS_DBGLVL		0
+
+/* Default options for ONMETIS */
+#define ONMETIS_CTYPE		MATCH_SHEM
+#define ONMETIS_ITYPE		IPART_GGPKL
+#define ONMETIS_RTYPE		RTYPE_SEP1SIDED
+#define ONMETIS_DBGLVL		0
+#define ONMETIS_OFLAGS		OFLAG_COMPRESS
+#define ONMETIS_PFACTOR		-1
+#define ONMETIS_NSEPS		1
+
+/* Default options for McPMETIS */
+#define McPMETIS_CTYPE		MATCH_SHEBM_ONENORM
+#define McPMETIS_ITYPE		IPART_RANDOM
+#define McPMETIS_RTYPE		RTYPE_FM
+#define McPMETIS_DBGLVL		0
+
+/* Default options for McKMETIS */
+#define McKMETIS_CTYPE		MATCH_SHEBM_ONENORM
+#define McKMETIS_ITYPE		IPART_McHPMETIS
+#define McKMETIS_RTYPE		RTYPE_KWAYRANDOM
+#define McKMETIS_DBGLVL		0
+
+/* Default options for KVMETIS */
+#define KVMETIS_CTYPE		MATCH_SHEM
+#define KVMETIS_ITYPE		IPART_PMETIS
+#define KVMETIS_RTYPE		RTYPE_KWAYRANDOM
+#define KVMETIS_DBGLVL		0
+
+
+/* Operations supported by stand-alone code */
+#define OP_PMETIS		1
+#define OP_KMETIS		2
+#define OP_OEMETIS		3
+#define OP_ONMETIS		4
+#define OP_ONWMETIS		5
+#define OP_KVMETIS		6
+
+
+/* Matching Schemes */
+#define MATCH_RM		1
+#define MATCH_HEM		2
+#define MATCH_SHEM		3
+#define MATCH_SHEMKWAY		4
+#define MATCH_SHEBM_ONENORM	5
+#define MATCH_SHEBM_INFNORM	6
+#define MATCH_SBHEM_ONENORM	7
+#define MATCH_SBHEM_INFNORM	8
+
+/* Initial partitioning schemes for PMETIS and ONMETIS */
+#define IPART_GGPKL		1
+#define IPART_GGPKLNODE		2
+#define IPART_RANDOM		2
+
+/* Refinement schemes for PMETIS */
+#define RTYPE_FM		1
+
+/* Initial partitioning schemes for KMETIS */
+#define IPART_PMETIS		1
+
+/* Refinement schemes for KMETIS */
+#define RTYPE_KWAYRANDOM	1
+#define RTYPE_KWAYGREEDY	2
+#define RTYPE_KWAYRANDOM_MCONN	3
+
+/* Refinement schemes for ONMETIS */
+#define RTYPE_SEP2SIDED		1
+#define RTYPE_SEP1SIDED		2
+
+/* Initial Partitioning Schemes for McKMETIS */
+#define IPART_McPMETIS		1   	/* Simple McPMETIS */
+#define IPART_McHPMETIS		2	/* horizontally relaxed McPMETIS */
+
+#define UNMATCHED		-1
+
+#define HTABLE_EMPTY    	-1
+
+#define NGR_PASSES		4	/* Number of greedy refinement passes */
+#define NLGR_PASSES		5	/* Number of GR refinement during IPartition */
+
+#define LARGENIPARTS		8	/* Number of random initial partitions */
+#define SMALLNIPARTS		3	/* Number of random initial partitions */
+
+#define COARSEN_FRACTION	0.75	/* Node reduction between succesive coarsening levels */
+#define COARSEN_FRACTION2	0.90	/* Node reduction between succesive coarsening levels */
+#define UNBALANCE_FRACTION		1.05
+
+#define COMPRESSION_FRACTION		0.85
+
+#define ORDER_UNBALANCE_FRACTION	1.10
+
+#define MMDSWITCH		200
+
+#define HORIZONTAL_IMBALANCE		1.05
+
+/* Debug Levels */
+#define DBG_TIME	1		/* Perform timing analysis */
+#define DBG_OUTPUT	2
+#define DBG_COARSEN   	4		/* Show the coarsening progress */
+#define DBG_REFINE	8		/* Show info on communication during folding */
+#define DBG_IPART	16		/* Show info on initial partition */
+#define DBG_MOVEINFO	32		/* Show info on communication during folding */
+#define DBG_KWAYPINFO	64		/* Show info on communication during folding */
+#define DBG_SEPINFO	128		/* Show info on communication during folding */
diff --git a/Metis/estmem.c b/Metis/estmem.c
new file mode 100644
index 0000000000..576d0b645f
--- /dev/null
+++ b/Metis/estmem.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * estmem.c
+ *
+ * This file contains code for estimating the amount of memory required by
+ * the various routines in METIS
+ *
+ * Started 11/4/97
+ * George
+ *
+ * $Id: estmem.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+/*************************************************************************
+* This function computes how much memory will be required by the various
+* routines in METIS
+**************************************************************************/
+void METIS_EstimateMemory(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *optype, int *nbytes)
+{
+  int i, j, k, nedges, nlevels;
+  float vfraction, efraction, vmult, emult;
+  int coresize, gdata, rdata;
+
+  if (*numflag == 1)
+    Change2CNumbering(*nvtxs, xadj, adjncy);
+
+  nedges = xadj[*nvtxs];
+
+  InitRandom(-1);
+  EstimateCFraction(*nvtxs, xadj, adjncy, &vfraction, &efraction);
+
+  /* Estimate the amount of memory for coresize */
+  if (*optype == 2) 
+    coresize = nedges;
+  else
+    coresize = 0;
+  coresize += nedges + 11*(*nvtxs) + 4*1024 + 2*(NEG_GAINSPAN+PLUS_GAINSPAN+1)*(sizeof(ListNodeType *)/sizeof(idxtype));
+  coresize += 2*(*nvtxs);  /* add some more fore other vectors */
+
+  gdata = nedges;   /* Assume that the user does not pass weights */
+
+  nlevels = (int)(log(100.0/(*nvtxs))/log(vfraction) + .5);
+  vmult = 0.5 + (1.0 - pow(vfraction, nlevels))/(1.0 - vfraction);
+  emult = 1.0 + (1.0 - pow(efraction, nlevels+1))/(1.0 - efraction);
+
+  gdata += vmult*4*(*nvtxs) + emult*2*nedges;
+  if ((vmult-1.0)*4*(*nvtxs) + (emult-1.0)*2*nedges < 5*(*nvtxs))
+    rdata = 0;
+  else
+    rdata = 5*(*nvtxs);
+
+  *nbytes = sizeof(idxtype)*(coresize+gdata+rdata+(*nvtxs));
+
+  if (*numflag == 1)
+    Change2FNumbering2(*nvtxs, xadj, adjncy);
+}
+  
+
+/*************************************************************************
+* This function finds a matching using the HEM heuristic
+**************************************************************************/
+void EstimateCFraction(int nvtxs, idxtype *xadj, idxtype *adjncy, float *vfraction, float *efraction)
+{
+  int i, ii, j, cnvtxs, cnedges, maxidx;
+  idxtype *match, *cmap, *perm;
+
+  cmap = idxmalloc(nvtxs, "cmap");
+  match = idxsmalloc(nvtxs, UNMATCHED, "match");
+  perm = idxmalloc(nvtxs, "perm");
+  RandomPermute(nvtxs, perm, 1);
+
+  cnvtxs = 0;
+  for (ii=0; ii<nvtxs; ii++) {
+    i = perm[ii];
+
+    if (match[i] == UNMATCHED) {  /* Unmatched */
+      maxidx = i;
+
+      /* Find a random matching, subject to maxvwgt constraints */
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        if (match[adjncy[j]] == UNMATCHED) {
+          maxidx = adjncy[j];
+          break;
+        }
+      }
+
+      cmap[i] = cmap[maxidx] = cnvtxs++;
+      match[i] = maxidx;
+      match[maxidx] = i;
+    }
+  }
+
+  cnedges = ComputeCoarseGraphSize(nvtxs, xadj, adjncy, cnvtxs, cmap, match, perm);
+
+  *vfraction = (1.0*cnvtxs)/(1.0*nvtxs);
+  *efraction = (1.0*cnedges)/(1.0*xadj[nvtxs]);
+
+  GKfree(&cmap, &match, &perm, LTERM);
+}
+
+
+
+
+/*************************************************************************
+* This function computes the size of the coarse graph
+**************************************************************************/
+int ComputeCoarseGraphSize(int nvtxs, idxtype *xadj, idxtype *adjncy, int cnvtxs, idxtype *cmap, idxtype *match, idxtype *perm)
+{
+  int i, j, k, istart, iend, nedges, cnedges, v, u;
+  idxtype *htable;
+
+  htable = idxsmalloc(cnvtxs, -1, "htable");
+
+  cnvtxs = cnedges = 0;
+  for (i=0; i<nvtxs; i++) {
+    v = perm[i];
+    if (cmap[v] != cnvtxs) 
+      continue;
+
+    htable[cnvtxs] = cnvtxs;
+
+    u = match[v];
+
+    istart = xadj[v];
+    iend = xadj[v+1];
+    for (j=istart; j<iend; j++) {
+      k = cmap[adjncy[j]];
+      if (htable[k] != cnvtxs) {
+        htable[k] = cnvtxs;
+        cnedges++;
+      }
+    }
+
+    if (v != u) { 
+      istart = xadj[u];
+      iend = xadj[u+1];
+      for (j=istart; j<iend; j++) {
+        k = cmap[adjncy[j]];
+        if (htable[k] != cnvtxs) {
+          htable[k] = cnvtxs;
+          cnedges++;
+        }
+      }
+    }
+    cnvtxs++;
+  }
+
+  GKfree(&htable, LTERM);
+
+  return cnedges;
+}
+
+
diff --git a/Metis/fm.c b/Metis/fm.c
new file mode 100644
index 0000000000..341d2b4f73
--- /dev/null
+++ b/Metis/fm.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * fm.c
+ *
+ * This file contains code that implements the edge-based FM refinement
+ *
+ * Started 7/23/97
+ * George
+ *
+ * $Id: fm.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function performs an edge-based FM refinement
+**************************************************************************/
+void FM_2WayEdgeRefine(CtrlType *ctrl, GraphType *graph, int *tpwgts, int npasses)
+{
+  int i, ii, j, k, kwgt, nvtxs, nbnd, nswaps, from, to, pass, me, limit, tmp;
+  idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind, *pwgts;
+  idxtype *moved, *swaps, *perm;
+  PQueueType parts[2];
+  int higain, oldgain, mincut, mindiff, origdiff, initcut, newcut, mincutorder, avgvwgt;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  vwgt = graph->vwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+  where = graph->where;
+  id = graph->id;
+  ed = graph->ed;
+  pwgts = graph->pwgts;
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+
+  moved = idxwspacemalloc(ctrl, nvtxs);
+  swaps = idxwspacemalloc(ctrl, nvtxs);
+  perm = idxwspacemalloc(ctrl, nvtxs);
+
+  limit = amin(amax(0.01*nvtxs, 15), 100);
+  avgvwgt = amin((pwgts[0]+pwgts[1])/20, 2*(pwgts[0]+pwgts[1])/nvtxs);
+
+  tmp = graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)];
+  PQueueInit(ctrl, &parts[0], nvtxs, tmp);
+  PQueueInit(ctrl, &parts[1], nvtxs, tmp);
+
+  IFSET(ctrl->dbglvl, DBG_REFINE, 
+     printf("Partitions: [%6d %6d] T[%6d %6d], Nv-Nb[%6d %6d]. ICut: %6d\n",
+             pwgts[0], pwgts[1], tpwgts[0], tpwgts[1], graph->nvtxs, graph->nbnd, graph->mincut));
+
+  origdiff = abs(tpwgts[0]-pwgts[0]);
+  idxset(nvtxs, -1, moved);
+  for (pass=0; pass<npasses; pass++) { /* Do a number of passes */
+    PQueueReset(&parts[0]);
+    PQueueReset(&parts[1]);
+
+    mincutorder = -1;
+    newcut = mincut = initcut = graph->mincut;
+    mindiff = abs(tpwgts[0]-pwgts[0]);
+
+    ASSERT(ComputeCut(graph, where) == graph->mincut);
+    ASSERT(CheckBnd(graph));
+
+    /* Insert boundary nodes in the priority queues */
+    nbnd = graph->nbnd;
+    RandomPermute(nbnd, perm, 1);
+    for (ii=0; ii<nbnd; ii++) {
+      i = perm[ii];
+      ASSERT(ed[bndind[i]] > 0 || id[bndind[i]] == 0);
+      ASSERT(bndptr[bndind[i]] != -1);
+      PQueueInsert(&parts[where[bndind[i]]], bndind[i], ed[bndind[i]]-id[bndind[i]]);
+    }
+
+    for (nswaps=0; nswaps<nvtxs; nswaps++) {
+      from = (tpwgts[0]-pwgts[0] < tpwgts[1]-pwgts[1] ? 0 : 1);
+      to = (from+1)%2;
+
+      if ((higain = PQueueGetMax(&parts[from])) == -1)
+        break;
+      ASSERT(bndptr[higain] != -1);
+
+      newcut -= (ed[higain]-id[higain]);
+      INC_DEC(pwgts[to], pwgts[from], vwgt[higain]);
+
+      if ((newcut < mincut && abs(tpwgts[0]-pwgts[0]) <= origdiff+avgvwgt) || 
+          (newcut == mincut && abs(tpwgts[0]-pwgts[0]) < mindiff)) {
+        mincut = newcut;
+        mindiff = abs(tpwgts[0]-pwgts[0]);
+        mincutorder = nswaps;
+      }
+      else if (nswaps-mincutorder > limit) { /* We hit the limit, undo last move */
+        newcut += (ed[higain]-id[higain]);
+        INC_DEC(pwgts[from], pwgts[to], vwgt[higain]);
+        break;
+      }
+
+      where[higain] = to;
+      moved[higain] = nswaps;
+      swaps[nswaps] = higain;
+
+      IFSET(ctrl->dbglvl, DBG_MOVEINFO, 
+        printf("Moved %6d from %d. [%3d %3d] %5d [%4d %4d]\n", higain, from, ed[higain]-id[higain], vwgt[higain], newcut, pwgts[0], pwgts[1]));
+
+      /**************************************************************
+      * Update the id[i]/ed[i] values of the affected nodes
+      ***************************************************************/
+      SWAP(id[higain], ed[higain], tmp);
+      if (ed[higain] == 0 && xadj[higain] < xadj[higain+1]) 
+        BNDDelete(nbnd, bndind,  bndptr, higain);
+
+      for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+        k = adjncy[j];
+        oldgain = ed[k]-id[k];
+
+        kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
+        INC_DEC(id[k], ed[k], kwgt);
+
+        /* Update its boundary information and queue position */
+        if (bndptr[k] != -1) { /* If k was a boundary vertex */
+          if (ed[k] == 0) { /* Not a boundary vertex any more */
+            BNDDelete(nbnd, bndind, bndptr, k);
+            if (moved[k] == -1)  /* Remove it if in the queues */
+              PQueueDelete(&parts[where[k]], k, oldgain);
+          }
+          else { /* If it has not been moved, update its position in the queue */
+            if (moved[k] == -1)
+              PQueueUpdate(&parts[where[k]], k, oldgain, ed[k]-id[k]);
+          }
+        }
+        else {
+          if (ed[k] > 0) {  /* It will now become a boundary vertex */
+            BNDInsert(nbnd, bndind, bndptr, k);
+            if (moved[k] == -1) 
+              PQueueInsert(&parts[where[k]], k, ed[k]-id[k]);
+          }
+        }
+      }
+
+    }
+
+
+    /****************************************************************
+    * Roll back computations
+    *****************************************************************/
+    for (i=0; i<nswaps; i++)
+      moved[swaps[i]] = -1;  /* reset moved array */
+    for (nswaps--; nswaps>mincutorder; nswaps--) {
+      higain = swaps[nswaps];
+
+      to = where[higain] = (where[higain]+1)%2;
+      SWAP(id[higain], ed[higain], tmp);
+      if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1])
+        BNDDelete(nbnd, bndind,  bndptr, higain);
+      else if (ed[higain] > 0 && bndptr[higain] == -1)
+        BNDInsert(nbnd, bndind,  bndptr, higain);
+
+      INC_DEC(pwgts[to], pwgts[(to+1)%2], vwgt[higain]);
+      for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+        k = adjncy[j];
+
+        kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
+        INC_DEC(id[k], ed[k], kwgt);
+
+        if (bndptr[k] != -1 && ed[k] == 0)
+          BNDDelete(nbnd, bndind, bndptr, k);
+        if (bndptr[k] == -1 && ed[k] > 0)
+          BNDInsert(nbnd, bndind, bndptr, k);
+      }
+    }
+
+    IFSET(ctrl->dbglvl, DBG_REFINE, 
+      printf("\tMinimum cut: %6d at %5d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, mincutorder, pwgts[0], pwgts[1], nbnd));
+
+    graph->mincut = mincut;
+    graph->nbnd = nbnd;
+
+    if (mincutorder == -1 || mincut == initcut)
+      break;
+  }
+
+  PQueueFree(ctrl, &parts[0]);
+  PQueueFree(ctrl, &parts[1]);
+
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+
+}
+
+
diff --git a/Metis/fortran.c b/Metis/fortran.c
new file mode 100644
index 0000000000..7d84eae989
--- /dev/null
+++ b/Metis/fortran.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * fortran.c
+ *
+ * This file contains code for the fortran to C interface
+ *
+ * Started 8/19/97
+ * George
+ *
+ * $Id: fortran.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function changes the numbering to start from 0 instead of 1
+**************************************************************************/
+void Change2CNumbering(int nvtxs, idxtype *xadj, idxtype *adjncy)
+{
+  int i, nedges;
+
+  for (i=0; i<=nvtxs; i++)
+    xadj[i]--;
+
+  nedges = xadj[nvtxs];
+  for (i=0; i<nedges; i++)
+    adjncy[i]--;
+}
+
+/*************************************************************************
+* This function changes the numbering to start from 1 instead of 0
+**************************************************************************/
+void Change2FNumbering(int nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vector)
+{
+  int i, nedges;
+
+  for (i=0; i<nvtxs; i++)
+    vector[i]++;
+
+  nedges = xadj[nvtxs];
+  for (i=0; i<nedges; i++)
+    adjncy[i]++;
+
+  for (i=0; i<=nvtxs; i++)
+    xadj[i]++;
+}
+
+/*************************************************************************
+* This function changes the numbering to start from 1 instead of 0
+**************************************************************************/
+void Change2FNumbering2(int nvtxs, idxtype *xadj, idxtype *adjncy)
+{
+  int i, nedges;
+
+  nedges = xadj[nvtxs];
+  for (i=0; i<nedges; i++)
+    adjncy[i]++;
+
+  for (i=0; i<=nvtxs; i++)
+    xadj[i]++;
+}
+
+
+
+/*************************************************************************
+* This function changes the numbering to start from 1 instead of 0
+**************************************************************************/
+void Change2FNumberingOrder(int nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *v1, idxtype *v2)
+{
+  int i, nedges;
+
+  for (i=0; i<nvtxs; i++) {
+    v1[i]++;
+    v2[i]++;
+  }
+
+  nedges = xadj[nvtxs];
+  for (i=0; i<nedges; i++)
+    adjncy[i]++;
+
+  for (i=0; i<=nvtxs; i++)
+    xadj[i]++;
+
+}
+
+
+
+/*************************************************************************
+* This function changes the numbering to start from 0 instead of 1
+**************************************************************************/
+void ChangeMesh2CNumbering(int n, idxtype *mesh)
+{
+  int i;
+
+  for (i=0; i<n; i++)
+    mesh[i]--;
+
+}
+
+
+/*************************************************************************
+* This function changes the numbering to start from 1 instead of 0
+**************************************************************************/
+void ChangeMesh2FNumbering(int n, idxtype *mesh, int nvtxs, idxtype *xadj, idxtype *adjncy)
+{
+  int i, nedges;
+
+  for (i=0; i<n; i++)
+    mesh[i]++;
+
+  nedges = xadj[nvtxs];
+  for (i=0; i<nedges; i++)
+    adjncy[i]++;
+
+  for (i=0; i<=nvtxs; i++)
+    xadj[i]++;
+
+}
+
+
+/*************************************************************************
+* This function changes the numbering to start from 1 instead of 0
+**************************************************************************/
+void ChangeMesh2FNumbering2(int n, idxtype *mesh, int ne, int nn, idxtype *epart, idxtype *npart)
+{
+  int i, nedges;
+
+  for (i=0; i<n; i++)
+    mesh[i]++;
+
+  for (i=0; i<ne; i++)
+    epart[i]++;
+
+  for (i=0; i<nn; i++)
+    npart[i]++;
+
+}
+
diff --git a/Metis/frename.c b/Metis/frename.c
new file mode 100644
index 0000000000..0ef94ab1b4
--- /dev/null
+++ b/Metis/frename.c
@@ -0,0 +1,312 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * frename.c
+ * 
+ * This file contains some renaming routines to deal with different Fortran compilers
+ *
+ * Started 9/15/97
+ * George
+ *
+ * $Id: frename.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+void METIS_PARTGRAPHRECURSIVE(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
+{
+  METIS_PartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part);
+}
+void metis_partgraphrecursive(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
+{ 
+  METIS_PartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); 
+}
+void metis_partgraphrecursive_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
+{
+  METIS_PartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part);
+}
+void metis_partgraphrecursive__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
+{
+  METIS_PartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part);
+}
+
+
+void METIS_WPARTGRAPHRECURSIVE(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part)
+{
+  METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part);
+}
+void metis_wpartgraphrecursive(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part)
+{
+  METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part);
+}
+void metis_wpartgraphrecursive_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part)
+{
+  METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part);
+}
+void metis_wpartgraphrecursive__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part)
+{
+  METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part);
+}
+
+
+
+void METIS_PARTGRAPHKWAY(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
+{
+  METIS_PartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part);
+}
+void metis_partgraphkway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
+{
+  METIS_PartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part);
+}
+void metis_partgraphkway_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
+{
+  METIS_PartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part);
+}
+void metis_partgraphkway__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
+{
+  METIS_PartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part);
+}
+
+
+
+void METIS_WPARTGRAPHKWAY(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part)
+{
+  METIS_WPartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part);
+}
+void metis_wpartgraphkway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part)
+{
+  METIS_WPartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part);
+}
+void metis_wpartgraphkway_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part)
+{
+  METIS_WPartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part);
+}
+void metis_wpartgraphkway__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part)
+{
+  METIS_WPartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part);
+}
+
+
+
+void METIS_EDGEND(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm)
+{
+  METIS_EdgeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm);
+}
+void metis_edgend(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm)
+{
+  METIS_EdgeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm);
+}
+void metis_edgend_(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm)
+{
+  METIS_EdgeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm);
+}
+void metis_edgend__(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm)
+{
+  METIS_EdgeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm);
+}
+
+
+
+void METIS_NODEND(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm)
+{
+  METIS_NodeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm);
+}
+void metis_nodend(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm)
+{
+  METIS_NodeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm);
+}
+void metis_nodend_(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm)
+{
+  METIS_NodeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm);
+}
+void metis_nodend__(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm)
+{
+  METIS_NodeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm);
+}
+
+
+
+void METIS_NODEWND(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, int *numflag, int *options, idxtype *perm, idxtype *iperm)
+{
+  METIS_NodeWND(nvtxs, xadj, adjncy, vwgt, numflag, options, perm, iperm);
+}
+void metis_nodewnd(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, int *numflag, int *options, idxtype *perm, idxtype *iperm)
+{
+  METIS_NodeWND(nvtxs, xadj, adjncy, vwgt, numflag, options, perm, iperm);
+}
+void metis_nodewnd_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, int *numflag, int *options, idxtype *perm, idxtype *iperm)
+{
+  METIS_NodeWND(nvtxs, xadj, adjncy, vwgt, numflag, options, perm, iperm);
+}
+void metis_nodewnd__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, int *numflag, int *options, idxtype *perm, idxtype *iperm)
+{
+  METIS_NodeWND(nvtxs, xadj, adjncy, vwgt, numflag, options, perm, iperm);
+}
+
+
+
+void METIS_PARTMESHNODAL(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
+{
+  METIS_PartMeshNodal(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart);
+}
+void metis_partmeshnodal(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
+{
+  METIS_PartMeshNodal(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart);
+}
+void metis_partmeshnodal_(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
+{
+  METIS_PartMeshNodal(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart);
+}
+void metis_partmeshnodal__(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
+{
+  METIS_PartMeshNodal(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart);
+}
+
+
+void METIS_PARTMESHDUAL(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
+{
+  METIS_PartMeshDual(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart);
+}
+void metis_partmeshdual(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
+{
+  METIS_PartMeshDual(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart);
+}
+void metis_partmeshdual_(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
+{
+  METIS_PartMeshDual(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart);
+}
+void metis_partmeshdual__(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
+{
+  METIS_PartMeshDual(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart);
+}
+
+
+void METIS_MESHTONODAL(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy)
+{
+  METIS_MeshToNodal(ne, nn, elmnts, etype, numflag, dxadj, dadjncy);
+}
+void metis_meshtonodal(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy)
+{
+  METIS_MeshToNodal(ne, nn, elmnts, etype, numflag, dxadj, dadjncy);
+}
+void metis_meshtonodal_(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy)
+{
+  METIS_MeshToNodal(ne, nn, elmnts, etype, numflag, dxadj, dadjncy);
+}
+void metis_meshtonodal__(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy)
+{
+  METIS_MeshToNodal(ne, nn, elmnts, etype, numflag, dxadj, dadjncy);
+}
+
+
+void METIS_MESHTODUAL(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy)
+{
+  METIS_MeshToDual(ne, nn, elmnts, etype, numflag, dxadj, dadjncy);
+}
+void metis_meshtodual(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy)
+{
+  METIS_MeshToDual(ne, nn, elmnts, etype, numflag, dxadj, dadjncy);
+}
+void metis_meshtodual_(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy)
+{
+  METIS_MeshToDual(ne, nn, elmnts, etype, numflag, dxadj, dadjncy);
+}
+void metis_meshtodual__(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy)
+{
+  METIS_MeshToDual(ne, nn, elmnts, etype, numflag, dxadj, dadjncy);
+}
+
+
+void METIS_ESTIMATEMEMORY(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *optype, int *nbytes)
+{
+  METIS_EstimateMemory(nvtxs, xadj, adjncy, numflag, optype, nbytes);
+}
+void metis_estimatememory(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *optype, int *nbytes)
+{
+  METIS_EstimateMemory(nvtxs, xadj, adjncy, numflag, optype, nbytes);
+}
+void metis_estimatememory_(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *optype, int *nbytes)
+{
+  METIS_EstimateMemory(nvtxs, xadj, adjncy, numflag, optype, nbytes);
+}
+void metis_estimatememory__(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *optype, int *nbytes)
+{
+  METIS_EstimateMemory(nvtxs, xadj, adjncy, numflag, optype, nbytes);
+}
+
+
+
+void METIS_MCPARTGRAPHRECURSIVE(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
+{
+  METIS_mCPartGraphRecursive(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part);
+}
+void metis_mcpartgraphrecursive(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
+{
+  METIS_mCPartGraphRecursive(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part);
+}
+void metis_mcpartgraphrecursive_(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
+{
+  METIS_mCPartGraphRecursive(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part);
+}
+void metis_mcpartgraphrecursive__(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
+{
+  METIS_mCPartGraphRecursive(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part);
+}
+
+
+void METIS_MCPARTGRAPHKWAY(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *rubvec, int *options, int *edgecut, idxtype *part)
+{
+  METIS_mCPartGraphKway(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, rubvec, options, edgecut, part);
+}
+void metis_mcpartgraphkway(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *rubvec, int *options, int *edgecut, idxtype *part)
+{
+  METIS_mCPartGraphKway(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, rubvec, options, edgecut, part);
+}
+void metis_mcpartgraphkway_(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *rubvec, int *options, int *edgecut, idxtype *part)
+{
+  METIS_mCPartGraphKway(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, rubvec, options, edgecut, part);
+}
+void metis_mcpartgraphkway__(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *rubvec, int *options, int *edgecut, idxtype *part)
+{
+  METIS_mCPartGraphKway(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, rubvec, options, edgecut, part);
+}
+
+
+void METIS_PARTGRAPHVKWAY(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, int *options, int *volume, idxtype *part)
+{
+  METIS_PartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, options, volume, part);
+}
+void metis_partgraphvkway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, int *options, int *volume, idxtype *part)
+{
+  METIS_PartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, options, volume, part);
+}
+void metis_partgraphvkway_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, int *options, int *volume, idxtype *part)
+{
+  METIS_PartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, options, volume, part);
+}
+void metis_partgraphvkway__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, int *options, int *volume, idxtype *part)
+{
+  METIS_PartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, options, volume, part);
+}
+
+void METIS_WPARTGRAPHVKWAY(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *volume, idxtype *part)
+{
+  METIS_WPartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, tpwgts, options, volume, part);
+}
+void metis_wpartgraphvkway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *volume, idxtype *part)
+{
+  METIS_WPartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, tpwgts, options, volume, part);
+}
+void metis_wpartgraphvkway_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *volume, idxtype *part)
+{
+  METIS_WPartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, tpwgts, options, volume, part);
+}
+void metis_wpartgraphvkway__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *volume, idxtype *part)
+{
+  METIS_WPartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, tpwgts, options, volume, part);
+}
+
+
+
diff --git a/Metis/graph.c b/Metis/graph.c
new file mode 100644
index 0000000000..5bb06c51de
--- /dev/null
+++ b/Metis/graph.c
@@ -0,0 +1,616 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * graph.c
+ *
+ * This file contains functions that deal with setting up the graphs
+ * for METIS.
+ *
+ * Started 7/25/97
+ * George
+ *
+ * $Id: graph.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+/*************************************************************************
+* This function sets up the graph from the user input
+**************************************************************************/
+void SetUpGraph(GraphType *graph, int OpType, int nvtxs, int ncon,
+       idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int wgtflag)
+{
+  int i, j, k, sum, gsize;
+  float *nvwgt;
+  idxtype tvwgt[MAXNCON];
+
+  if (OpType == OP_KMETIS && ncon == 1 && (wgtflag&2) == 0 && (wgtflag&1) == 0) {
+    SetUpGraphKway(graph, nvtxs, xadj, adjncy);
+    return;
+  }
+
+  InitGraph(graph);
+
+  graph->nvtxs = nvtxs;
+  graph->nedges = xadj[nvtxs];
+  graph->ncon = ncon;
+  graph->xadj = xadj;
+  graph->adjncy = adjncy;
+
+  if (ncon == 1) { /* We are in the non mC mode */
+    gsize = 0; 
+    if ((wgtflag&2) == 0)
+      gsize += nvtxs;
+    if ((wgtflag&1) == 0)
+      gsize += graph->nedges;
+
+    gsize += 2*nvtxs;
+
+    graph->gdata = idxmalloc(gsize, "SetUpGraph: gdata");
+
+    /* Create the vertex/edge weight vectors if they are not supplied */
+    gsize = 0;
+    if ((wgtflag&2) == 0) {
+      vwgt = graph->vwgt = idxset(nvtxs, 1, graph->gdata);
+      gsize += nvtxs;
+    }
+    else
+      graph->vwgt = vwgt;
+
+    if ((wgtflag&1) == 0) {
+      adjwgt = graph->adjwgt = idxset(graph->nedges, 1, graph->gdata+gsize);
+      gsize += graph->nedges;
+    }
+    else
+      graph->adjwgt = adjwgt;
+
+
+    /* Compute the initial values of the adjwgtsum */
+    graph->adjwgtsum = graph->gdata + gsize;
+    gsize += nvtxs;
+
+    for (i=0; i<nvtxs; i++) {
+      sum = 0;
+      for (j=xadj[i]; j<xadj[i+1]; j++)
+        sum += adjwgt[j];
+      graph->adjwgtsum[i] = sum;
+    }
+
+    graph->cmap = graph->gdata + gsize;
+    gsize += nvtxs;
+
+  }
+  else {  /* Set up the graph in MOC mode */
+    gsize = 0; 
+    if ((wgtflag&1) == 0)
+      gsize += graph->nedges;
+
+    gsize += 2*nvtxs;
+
+    graph->gdata = idxmalloc(gsize, "SetUpGraph: gdata");
+    gsize = 0;
+
+    for (i=0; i<ncon; i++) 
+      tvwgt[i] = idxsum_strd(nvtxs, vwgt+i, ncon);
+    
+    nvwgt = graph->nvwgt = fmalloc(ncon*nvtxs, "SetUpGraph: nvwgt");
+
+    for (i=0; i<nvtxs; i++) {
+      for (j=0; j<ncon; j++) 
+        nvwgt[i*ncon+j] = (1.0*vwgt[i*ncon+j])/(1.0*tvwgt[j]);
+    }
+
+
+    /* Create the edge weight vectors if they are not supplied */
+    if ((wgtflag&1) == 0) {
+      adjwgt = graph->adjwgt = idxset(graph->nedges, 1, graph->gdata+gsize);
+      gsize += graph->nedges;
+    }
+    else
+      graph->adjwgt = adjwgt;
+
+    /* Compute the initial values of the adjwgtsum */
+    graph->adjwgtsum = graph->gdata + gsize;
+    gsize += nvtxs;
+
+    for (i=0; i<nvtxs; i++) {
+      sum = 0;
+      for (j=xadj[i]; j<xadj[i+1]; j++)
+        sum += adjwgt[j];
+      graph->adjwgtsum[i] = sum;
+    }
+
+    graph->cmap = graph->gdata + gsize;
+    gsize += nvtxs;
+
+  }
+
+  if (OpType != OP_KMETIS && OpType != OP_KVMETIS) {
+    graph->label = idxmalloc(nvtxs, "SetUpGraph: label");
+
+    for (i=0; i<nvtxs; i++)
+      graph->label[i] = i;
+  }
+
+}
+
+
+/*************************************************************************
+* This function sets up the graph from the user input
+**************************************************************************/
+void SetUpGraphKway(GraphType *graph, int nvtxs, idxtype *xadj, idxtype *adjncy)
+{
+  int i;
+
+  InitGraph(graph);
+
+  graph->nvtxs = nvtxs;
+  graph->nedges = xadj[nvtxs];
+  graph->ncon = 1;
+  graph->xadj = xadj;
+  graph->vwgt = NULL;
+  graph->adjncy = adjncy;
+  graph->adjwgt = NULL;
+
+  graph->gdata = idxmalloc(2*nvtxs, "SetUpGraph: gdata");
+  graph->adjwgtsum = graph->gdata;
+  graph->cmap = graph->gdata + nvtxs;
+
+  /* Compute the initial values of the adjwgtsum */
+  for (i=0; i<nvtxs; i++) 
+    graph->adjwgtsum[i] = xadj[i+1]-xadj[i];
+
+}
+
+
+
+/*************************************************************************
+* This function sets up the graph from the user input
+**************************************************************************/
+void SetUpGraph2(GraphType *graph, int nvtxs, int ncon, idxtype *xadj, 
+       idxtype *adjncy, float *nvwgt, idxtype *adjwgt)
+{
+  int i, j, sum;
+
+  InitGraph(graph);
+
+  graph->nvtxs = nvtxs;
+  graph->nedges = xadj[nvtxs];
+  graph->ncon = ncon;
+  graph->xadj = xadj;
+  graph->adjncy = adjncy;
+  graph->adjwgt = adjwgt;
+
+  graph->nvwgt = fmalloc(nvtxs*ncon, "SetUpGraph2: graph->nvwgt");
+  scopy(nvtxs*ncon, nvwgt, graph->nvwgt);
+
+  graph->gdata = idxmalloc(2*nvtxs, "SetUpGraph: gdata");
+
+  /* Compute the initial values of the adjwgtsum */
+  graph->adjwgtsum = graph->gdata;
+  for (i=0; i<nvtxs; i++) {
+    sum = 0;
+    for (j=xadj[i]; j<xadj[i+1]; j++)
+      sum += adjwgt[j];
+    graph->adjwgtsum[i] = sum;
+  }
+
+  graph->cmap = graph->gdata+nvtxs;
+
+  graph->label = idxmalloc(nvtxs, "SetUpGraph: label");
+  for (i=0; i<nvtxs; i++)
+    graph->label[i] = i;
+
+}
+
+
+/*************************************************************************
+* This function sets up the graph from the user input
+**************************************************************************/
+void VolSetUpGraph(GraphType *graph, int OpType, int nvtxs, int ncon, idxtype *xadj, 
+                   idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int wgtflag)
+{
+  int i, j, k, sum, gsize;
+  idxtype *adjwgt;
+  float *nvwgt;
+  idxtype tvwgt[MAXNCON];
+
+  InitGraph(graph);
+
+  graph->nvtxs = nvtxs;
+  graph->nedges = xadj[nvtxs];
+  graph->ncon = ncon;
+  graph->xadj = xadj;
+  graph->adjncy = adjncy;
+
+  if (ncon == 1) { /* We are in the non mC mode */
+    gsize = graph->nedges;  /* This is for the edge weights */
+    if ((wgtflag&2) == 0)
+      gsize += nvtxs; /* vwgts */
+    if ((wgtflag&1) == 0)
+      gsize += nvtxs; /* vsize */
+
+    gsize += 2*nvtxs;
+
+    graph->gdata = idxmalloc(gsize, "SetUpGraph: gdata");
+
+    /* Create the vertex/edge weight vectors if they are not supplied */
+    gsize = 0;
+    if ((wgtflag&2) == 0) {
+      vwgt = graph->vwgt = idxset(nvtxs, 1, graph->gdata);
+      gsize += nvtxs;
+    }
+    else
+      graph->vwgt = vwgt;
+
+    if ((wgtflag&1) == 0) {
+      vsize = graph->vsize = idxset(nvtxs, 1, graph->gdata);
+      gsize += nvtxs;
+    }
+    else
+      graph->vsize = vsize;
+
+    /* Allocate memory for edge weights and initialize them to the sum of the vsize */
+    adjwgt = graph->adjwgt = graph->gdata+gsize;
+    gsize += graph->nedges;
+
+    for (i=0; i<nvtxs; i++) {
+      for (j=xadj[i]; j<xadj[i+1]; j++)
+        adjwgt[j] = 1+vsize[i]+vsize[adjncy[j]];
+    }
+
+
+    /* Compute the initial values of the adjwgtsum */
+    graph->adjwgtsum = graph->gdata + gsize;
+    gsize += nvtxs;
+
+    for (i=0; i<nvtxs; i++) {
+      sum = 0;
+      for (j=xadj[i]; j<xadj[i+1]; j++)
+        sum += adjwgt[j];
+      graph->adjwgtsum[i] = sum;
+    }
+
+    graph->cmap = graph->gdata + gsize;
+    gsize += nvtxs;
+
+  }
+  else {  /* Set up the graph in MOC mode */
+    gsize = graph->nedges; 
+    if ((wgtflag&1) == 0)
+      gsize += nvtxs;
+
+    gsize += 2*nvtxs;
+
+    graph->gdata = idxmalloc(gsize, "SetUpGraph: gdata");
+    gsize = 0;
+
+    /* Create the normalized vertex weights along each constrain */
+    if ((wgtflag&2) == 0) 
+      vwgt = idxsmalloc(nvtxs, 1, "SetUpGraph: vwgt");
+
+    for (i=0; i<ncon; i++) 
+      tvwgt[i] = idxsum_strd(nvtxs, vwgt+i, ncon);
+    
+    nvwgt = graph->nvwgt = fmalloc(ncon*nvtxs, "SetUpGraph: nvwgt");
+
+    for (i=0; i<nvtxs; i++) {
+      for (j=0; j<ncon; j++) 
+        nvwgt[i*ncon+j] = (1.0*vwgt[i*ncon+j])/(1.0*tvwgt[j]);
+    }
+    if ((wgtflag&2) == 0) 
+      free(vwgt);
+
+
+    /* Create the vsize vector if it is not supplied */
+    if ((wgtflag&1) == 0) {
+      vsize = graph->vsize = idxset(nvtxs, 1, graph->gdata);
+      gsize += nvtxs;
+    }
+    else
+      graph->vsize = vsize;
+
+    /* Allocate memory for edge weights and initialize them to the sum of the vsize */
+    adjwgt = graph->adjwgt = graph->gdata+gsize;
+    gsize += graph->nedges;
+
+    for (i=0; i<nvtxs; i++) {
+      for (j=xadj[i]; j<xadj[i+1]; j++)
+        adjwgt[j] = 1+vsize[i]+vsize[adjncy[j]];
+    }
+
+    /* Compute the initial values of the adjwgtsum */
+    graph->adjwgtsum = graph->gdata + gsize;
+    gsize += nvtxs;
+
+    for (i=0; i<nvtxs; i++) {
+      sum = 0;
+      for (j=xadj[i]; j<xadj[i+1]; j++)
+        sum += adjwgt[j];
+      graph->adjwgtsum[i] = sum;
+    }
+
+    graph->cmap = graph->gdata + gsize;
+    gsize += nvtxs;
+
+  }
+
+  if (OpType != OP_KVMETIS) {
+    graph->label = idxmalloc(nvtxs, "SetUpGraph: label");
+
+    for (i=0; i<nvtxs; i++)
+      graph->label[i] = i;
+  }
+
+}
+
+
+/*************************************************************************
+* This function randomly permutes the adjacency lists of a graph
+**************************************************************************/
+void RandomizeGraph(GraphType *graph)
+{
+  int i, j, k, l, tmp, nvtxs;
+  idxtype *xadj, *adjncy, *adjwgt;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  for (i=0; i<nvtxs; i++) {
+    l = xadj[i+1]-xadj[i];
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      k = xadj[i] + RandomInRange(l);
+      SWAP(adjncy[j], adjncy[k], tmp);
+      SWAP(adjwgt[j], adjwgt[k], tmp);
+    }
+  }
+}
+
+
+/*************************************************************************
+* This function checks whether or not partition pid is contigous
+**************************************************************************/
+int IsConnectedSubdomain(CtrlType *ctrl, GraphType *graph, int pid, int report)
+{
+  int i, j, k, nvtxs, first, last, nleft, ncmps, wgt;
+  idxtype *xadj, *adjncy, *where, *touched, *queue;
+  idxtype *cptr;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  where = graph->where;
+
+  touched = idxsmalloc(nvtxs, 0, "IsConnected: touched");
+  queue = idxmalloc(nvtxs, "IsConnected: queue");
+  cptr = idxmalloc(nvtxs, "IsConnected: cptr");
+
+  nleft = 0;
+  for (i=0; i<nvtxs; i++) {
+    if (where[i] == pid) 
+      nleft++;
+  }
+
+  for (i=0; i<nvtxs; i++) {
+    if (where[i] == pid) 
+      break;
+  }
+
+  touched[i] = 1;
+  queue[0] = i;
+  first = 0; last = 1;
+
+  cptr[0] = 0;  /* This actually points to queue */
+  ncmps = 0;
+  while (first != nleft) {
+    if (first == last) { /* Find another starting vertex */
+      cptr[++ncmps] = first;
+      for (i=0; i<nvtxs; i++) {
+        if (where[i] == pid && !touched[i])
+          break;
+      }
+      queue[last++] = i;
+      touched[i] = 1;
+    }
+
+    i = queue[first++];
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      k = adjncy[j];
+      if (where[k] == pid && !touched[k]) {
+        queue[last++] = k;
+        touched[k] = 1;
+      }
+    }
+  }
+  cptr[++ncmps] = first;
+
+  if (ncmps > 1 && report) {
+    printf("The graph has %d connected components in partition %d:\t", ncmps, pid);
+    for (i=0; i<ncmps; i++) {
+      wgt = 0;
+      for (j=cptr[i]; j<cptr[i+1]; j++)
+        wgt += graph->vwgt[queue[j]];
+      printf("[%5d %5d] ", cptr[i+1]-cptr[i], wgt);
+      /*
+      if (cptr[i+1]-cptr[i] == 1)
+        printf("[%d %d] ", queue[cptr[i]], xadj[queue[cptr[i]]+1]-xadj[queue[cptr[i]]]);
+      */
+    }
+    printf("\n");
+  }
+
+  GKfree(&touched, &queue, &cptr, LTERM);
+
+  return (ncmps == 1 ? 1 : 0);
+}
+
+
+/*************************************************************************
+* This function checks whether a graph is contigous or not
+**************************************************************************/
+int IsConnected(CtrlType *ctrl, GraphType *graph, int report)
+{
+  int i, j, k, nvtxs, first, last;
+  idxtype *xadj, *adjncy, *touched, *queue;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+
+  touched = idxsmalloc(nvtxs, 0, "IsConnected: touched");
+  queue = idxmalloc(nvtxs, "IsConnected: queue");
+
+  touched[0] = 1;
+  queue[0] = 0;
+  first = 0; last = 1;
+
+  while (first < last) {
+    i = queue[first++];
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      k = adjncy[j];
+      if (!touched[k]) {
+        queue[last++] = k;
+        touched[k] = 1;
+      }
+    }
+  }
+
+  if (first != nvtxs && report)
+    printf("The graph is not connected. It has %d disconnected vertices!\n", nvtxs-first);
+
+  return (first == nvtxs ? 1 : 0);
+}
+
+
+/*************************************************************************
+* This function checks whether or not partition pid is contigous
+**************************************************************************/
+int IsConnected2(GraphType *graph, int report)
+{
+  int i, j, k, nvtxs, first, last, nleft, ncmps, wgt;
+  idxtype *xadj, *adjncy, *where, *touched, *queue;
+  idxtype *cptr;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  where = graph->where;
+
+  touched = idxsmalloc(nvtxs, 0, "IsConnected: touched");
+  queue = idxmalloc(nvtxs, "IsConnected: queue");
+  cptr = idxmalloc(nvtxs, "IsConnected: cptr");
+
+  nleft = nvtxs;
+  touched[0] = 1;
+  queue[0] = 0;
+  first = 0; last = 1;
+
+  cptr[0] = 0;  /* This actually points to queue */
+  ncmps = 0;
+  while (first != nleft) {
+    if (first == last) { /* Find another starting vertex */
+      cptr[++ncmps] = first;
+      for (i=0; i<nvtxs; i++) {
+        if (!touched[i])
+          break;
+      }
+      queue[last++] = i;
+      touched[i] = 1;
+    }
+
+    i = queue[first++];
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      k = adjncy[j];
+      if (!touched[k]) {
+        queue[last++] = k;
+        touched[k] = 1;
+      }
+    }
+  }
+  cptr[++ncmps] = first;
+
+  if (ncmps > 1 && report) {
+    printf("%d connected components:\t", ncmps);
+    for (i=0; i<ncmps; i++) {
+      if (cptr[i+1]-cptr[i] > 200)
+        printf("[%5d] ", cptr[i+1]-cptr[i]);
+    }
+    printf("\n");
+  }
+
+  GKfree(&touched, &queue, &cptr, LTERM);
+
+  return (ncmps == 1 ? 1 : 0);
+}
+
+
+/*************************************************************************
+* This function returns the number of connected components in cptr,cind
+* The separator of the graph is used to split it and then find its components.
+**************************************************************************/
+int FindComponents(CtrlType *ctrl, GraphType *graph, idxtype *cptr, idxtype *cind)
+{
+  int i, j, k, nvtxs, first, last, nleft, ncmps, wgt;
+  idxtype *xadj, *adjncy, *where, *touched, *queue;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  where = graph->where;
+
+  touched = idxsmalloc(nvtxs, 0, "IsConnected: queue");
+
+  for (i=0; i<graph->nbnd; i++)
+    touched[graph->bndind[i]] = 1;
+
+  queue = cind;
+
+  nleft = 0;
+  for (i=0; i<nvtxs; i++) {
+    if (where[i] != 2) 
+      nleft++;
+  }
+
+  for (i=0; i<nvtxs; i++) {
+    if (where[i] != 2)
+      break;
+  }
+
+  touched[i] = 1;
+  queue[0] = i;
+  first = 0; last = 1;
+
+  cptr[0] = 0;  /* This actually points to queue */
+  ncmps = 0;
+  while (first != nleft) {
+    if (first == last) { /* Find another starting vertex */
+      cptr[++ncmps] = first;
+      for (i=0; i<nvtxs; i++) {
+        if (!touched[i])
+          break;
+      }
+      queue[last++] = i;
+      touched[i] = 1;
+    }
+
+    i = queue[first++];
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      k = adjncy[j];
+      if (!touched[k]) {
+        queue[last++] = k;
+        touched[k] = 1;
+      }
+    }
+  }
+  cptr[++ncmps] = first;
+
+  free(touched);
+
+  return ncmps;
+}
+
+
+
diff --git a/Metis/initpart.c b/Metis/initpart.c
new file mode 100644
index 0000000000..58b01056ee
--- /dev/null
+++ b/Metis/initpart.c
@@ -0,0 +1,422 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * initpart.c
+ *
+ * This file contains code that performs the initial partition of the
+ * coarsest graph
+ *
+ * Started 7/23/97
+ * George
+ *
+ * $Id: initpart.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+/*************************************************************************
+* This function computes the initial bisection of the coarsest graph
+**************************************************************************/
+void Init2WayPartition(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor) 
+{
+  int dbglvl;
+
+  dbglvl = ctrl->dbglvl;
+  IFSET(ctrl->dbglvl, DBG_REFINE, ctrl->dbglvl -= DBG_REFINE);
+  IFSET(ctrl->dbglvl, DBG_MOVEINFO, ctrl->dbglvl -= DBG_MOVEINFO);
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr));
+
+  switch (ctrl->IType) {
+    case IPART_GGPKL:
+      GrowBisection(ctrl, graph, tpwgts, ubfactor);
+      break;
+    case 3:
+      RandomBisection(ctrl, graph, tpwgts, ubfactor);
+      break;
+    default:
+      errexit("Unknown initial partition type: %d\n", ctrl->IType);
+  }
+
+  IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial Cut: %d\n", graph->mincut));
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr));
+  ctrl->dbglvl = dbglvl;
+
+/*
+  IsConnectedSubdomain(ctrl, graph, 0);
+  IsConnectedSubdomain(ctrl, graph, 1);
+*/
+}
+
+/*************************************************************************
+* This function computes the initial bisection of the coarsest graph
+**************************************************************************/
+void InitSeparator(CtrlType *ctrl, GraphType *graph, float ubfactor) 
+{
+  int dbglvl;
+
+  dbglvl = ctrl->dbglvl;
+  IFSET(ctrl->dbglvl, DBG_REFINE, ctrl->dbglvl -= DBG_REFINE);
+  IFSET(ctrl->dbglvl, DBG_MOVEINFO, ctrl->dbglvl -= DBG_MOVEINFO);
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr));
+
+  GrowBisectionNode(ctrl, graph, ubfactor);
+  Compute2WayNodePartitionParams(ctrl, graph);
+
+  IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial Sep: %d\n", graph->mincut));
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr));
+
+  ctrl->dbglvl = dbglvl;
+
+}
+
+
+
+/*************************************************************************
+* This function takes a graph and produces a bisection by using a region
+* growing algorithm. The resulting partition is returned in
+* graph->where
+**************************************************************************/
+void GrowBisection(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor)
+{
+  int i, j, k, nvtxs, drain, nleft, first, last, pwgts[2], minpwgt[2], maxpwgt[2], from, bestcut, icut, mincut, me, pass, nbfs;
+  idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where;
+  idxtype *queue, *touched, *gain, *bestwhere;
+
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  vwgt = graph->vwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  Allocate2WayPartitionMemory(ctrl, graph);
+  where = graph->where;
+
+  bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere");
+  queue = idxmalloc(nvtxs, "BisectGraph: queue");
+  touched = idxmalloc(nvtxs, "BisectGraph: touched");
+
+  ASSERTP(tpwgts[0]+tpwgts[1] == idxsum(nvtxs, vwgt), ("%d %d\n", tpwgts[0]+tpwgts[1], idxsum(nvtxs, vwgt)));
+
+  maxpwgt[0] = ubfactor*tpwgts[0];
+  maxpwgt[1] = ubfactor*tpwgts[1];
+  minpwgt[0] = (1.0/ubfactor)*tpwgts[0];
+  minpwgt[1] = (1.0/ubfactor)*tpwgts[1];
+
+  nbfs = (nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS);
+  bestcut = idxsum(nvtxs, graph->adjwgtsum)+1;  /* The +1 is for the 0 edges case */
+  for (; nbfs>0; nbfs--) {
+    idxset(nvtxs, 0, touched);
+
+    pwgts[1] = tpwgts[0]+tpwgts[1];
+    pwgts[0] = 0;
+
+    idxset(nvtxs, 1, where);
+
+    queue[0] = RandomInRange(nvtxs);
+    touched[queue[0]] = 1;
+    first = 0; last = 1;
+    nleft = nvtxs-1;
+    drain = 0;
+
+    /* Start the BFS from queue to get a partition */
+    for (;;) {
+      if (first == last) { /* Empty. Disconnected graph! */
+        if (nleft == 0 || drain)
+          break;
+
+        k = RandomInRange(nleft);
+        for (i=0; i<nvtxs; i++) {
+          if (touched[i] == 0) {
+            if (k == 0)
+              break;
+            else
+              k--;
+          }
+        }
+
+        queue[0] = i;
+        touched[i] = 1;
+        first = 0; last = 1;;
+        nleft--;
+      }
+
+      i = queue[first++];
+      if (pwgts[0] > 0 && pwgts[1]-vwgt[i] < minpwgt[1]) {
+        drain = 1;
+        continue;
+      }
+
+      where[i] = 0;
+      INC_DEC(pwgts[0], pwgts[1], vwgt[i]);
+      if (pwgts[1] <= maxpwgt[1])
+        break;
+
+      drain = 0;
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        k = adjncy[j];
+        if (touched[k] == 0) {
+          queue[last++] = k;
+          touched[k] = 1;
+          nleft--;
+        }
+      }
+    }
+
+    /* Check to see if we hit any bad limiting cases */
+    if (pwgts[1] == 0) { 
+      i = RandomInRange(nvtxs);
+      where[i] = 1;
+      INC_DEC(pwgts[1], pwgts[0], vwgt[i]);
+    }
+
+    /*************************************************************
+    * Do some partition refinement 
+    **************************************************************/
+    Compute2WayPartitionParams(ctrl, graph);
+    /*printf("IPART: %3d [%5d %5d] [%5d %5d] %5d\n", graph->nvtxs, pwgts[0], pwgts[1], graph->pwgts[0], graph->pwgts[1], graph->mincut); */
+
+    Balance2Way(ctrl, graph, tpwgts, ubfactor);
+    /*printf("BPART: [%5d %5d] %5d\n", graph->pwgts[0], graph->pwgts[1], graph->mincut);*/
+
+    FM_2WayEdgeRefine(ctrl, graph, tpwgts, 4);
+    /*printf("RPART: [%5d %5d] %5d\n", graph->pwgts[0], graph->pwgts[1], graph->mincut);*/
+
+    if (bestcut > graph->mincut) {
+      bestcut = graph->mincut;
+      idxcopy(nvtxs, where, bestwhere);
+      if (bestcut == 0)
+        break;
+    }
+  }
+
+  graph->mincut = bestcut;
+  idxcopy(nvtxs, bestwhere, where);
+
+  GKfree(&bestwhere, &queue, &touched, LTERM);
+}
+
+
+
+
+/*************************************************************************
+* This function takes a graph and produces a bisection by using a region
+* growing algorithm. The resulting partition is returned in
+* graph->where
+**************************************************************************/
+void GrowBisectionNode(CtrlType *ctrl, GraphType *graph, float ubfactor)
+{
+  int i, j, k, nvtxs, drain, nleft, first, last, pwgts[2], tpwgts[2], minpwgt[2], maxpwgt[2], from, bestcut, icut, mincut, me, pass, nbfs;
+  idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where, *bndind;
+  idxtype *queue, *touched, *gain, *bestwhere;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  vwgt = graph->vwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere");
+  queue = idxmalloc(nvtxs, "BisectGraph: queue");
+  touched = idxmalloc(nvtxs, "BisectGraph: touched");
+
+  tpwgts[0] = idxsum(nvtxs, vwgt);
+  tpwgts[1] = tpwgts[0]/2;
+  tpwgts[0] -= tpwgts[1];
+
+  maxpwgt[0] = ubfactor*tpwgts[0];
+  maxpwgt[1] = ubfactor*tpwgts[1];
+  minpwgt[0] = (1.0/ubfactor)*tpwgts[0];
+  minpwgt[1] = (1.0/ubfactor)*tpwgts[1];
+
+  /* Allocate memory for graph->rdata. Allocate sufficient memory for both edge and node */
+  graph->rdata = idxmalloc(5*nvtxs+3, "GrowBisectionNode: graph->rdata");
+  graph->pwgts    = graph->rdata;
+  graph->where    = graph->rdata + 3;
+  graph->bndptr   = graph->rdata + nvtxs + 3;
+  graph->bndind   = graph->rdata + 2*nvtxs + 3;
+  graph->nrinfo   = (NRInfoType *)(graph->rdata + 3*nvtxs + 3);
+  graph->id       = graph->rdata + 3*nvtxs + 3;
+  graph->ed       = graph->rdata + 4*nvtxs + 3;
+  
+  where = graph->where;
+  bndind = graph->bndind;
+
+  nbfs = (nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS);
+  bestcut = tpwgts[0]+tpwgts[1];
+  for (nbfs++; nbfs>0; nbfs--) {
+    idxset(nvtxs, 0, touched);
+
+    pwgts[1] = tpwgts[0]+tpwgts[1];
+    pwgts[0] = 0;
+
+    idxset(nvtxs, 1, where);
+
+    queue[0] = RandomInRange(nvtxs);
+    touched[queue[0]] = 1;
+    first = 0; last = 1;
+    nleft = nvtxs-1;
+    drain = 0;
+
+    /* Start the BFS from queue to get a partition */
+    if (nbfs >= 1) {
+      for (;;) {
+        if (first == last) { /* Empty. Disconnected graph! */
+          if (nleft == 0 || drain)
+            break;
+  
+          k = RandomInRange(nleft);
+          for (i=0; i<nvtxs; i++) {
+            if (touched[i] == 0) {
+              if (k == 0)
+                break;
+              else
+                k--;
+            }
+          }
+
+          queue[0] = i;
+          touched[i] = 1;
+          first = 0; last = 1;;
+          nleft--;
+        }
+
+        i = queue[first++];
+        if (pwgts[1]-vwgt[i] < minpwgt[1]) {
+          drain = 1;
+          continue;
+        }
+
+        where[i] = 0;
+        INC_DEC(pwgts[0], pwgts[1], vwgt[i]);
+        if (pwgts[1] <= maxpwgt[1])
+          break;
+
+        drain = 0;
+        for (j=xadj[i]; j<xadj[i+1]; j++) {
+          k = adjncy[j];
+          if (touched[k] == 0) {
+            queue[last++] = k;
+            touched[k] = 1;
+            nleft--;
+          }
+        }
+      }
+    }
+
+    /*************************************************************
+    * Do some partition refinement 
+    **************************************************************/
+    Compute2WayPartitionParams(ctrl, graph);
+    Balance2Way(ctrl, graph, tpwgts, ubfactor);
+    FM_2WayEdgeRefine(ctrl, graph, tpwgts, 4);
+
+    /* Construct and refine the vertex separator */
+    for (i=0; i<graph->nbnd; i++) 
+      where[bndind[i]] = 2;
+
+    Compute2WayNodePartitionParams(ctrl, graph); 
+    FM_2WayNodeRefine(ctrl, graph, ubfactor, 6);
+
+    /* printf("ISep: [%d %d %d] %d\n", graph->pwgts[0], graph->pwgts[1], graph->pwgts[2], bestcut); */
+
+    if (bestcut > graph->mincut) {
+      bestcut = graph->mincut;
+      idxcopy(nvtxs, where, bestwhere);
+    }
+  }
+
+  graph->mincut = bestcut;
+  idxcopy(nvtxs, bestwhere, where);
+
+  Compute2WayNodePartitionParams(ctrl, graph); 
+
+  GKfree(&bestwhere, &queue, &touched, LTERM);
+}
+
+
+/*************************************************************************
+* This function takes a graph and produces a bisection by using a region
+* growing algorithm. The resulting partition is returned in
+* graph->where
+**************************************************************************/
+void RandomBisection(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor)
+{
+  int i, ii, j, k, nvtxs, pwgts[2], minpwgt[2], maxpwgt[2], from, bestcut, icut, mincut, me, pass, nbfs;
+  idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where;
+  idxtype *perm, *bestwhere;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  vwgt = graph->vwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  Allocate2WayPartitionMemory(ctrl, graph);
+  where = graph->where;
+
+  bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere");
+  perm = idxmalloc(nvtxs, "BisectGraph: queue");
+
+  ASSERTP(tpwgts[0]+tpwgts[1] == idxsum(nvtxs, vwgt), ("%d %d\n", tpwgts[0]+tpwgts[1], idxsum(nvtxs, vwgt)));
+
+  maxpwgt[0] = ubfactor*tpwgts[0];
+  maxpwgt[1] = ubfactor*tpwgts[1];
+  minpwgt[0] = (1.0/ubfactor)*tpwgts[0];
+  minpwgt[1] = (1.0/ubfactor)*tpwgts[1];
+
+  nbfs = (nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS);
+  bestcut = idxsum(nvtxs, graph->adjwgtsum)+1;  /* The +1 is for the 0 edges case */
+  for (; nbfs>0; nbfs--) {
+    RandomPermute(nvtxs, perm, 1);
+
+    idxset(nvtxs, 1, where);
+    pwgts[1] = tpwgts[0]+tpwgts[1];
+    pwgts[0] = 0;
+
+
+    if (nbfs != 1) {
+      for (ii=0; ii<nvtxs; ii++) {
+        i = perm[ii];
+        if (pwgts[0]+vwgt[i] < maxpwgt[0]) {
+          where[i] = 0;
+          pwgts[0] += vwgt[i];
+          pwgts[1] -= vwgt[i];
+          if (pwgts[0] > minpwgt[0])
+            break;
+        }
+      }
+    }
+
+    /*************************************************************
+    * Do some partition refinement 
+    **************************************************************/
+    Compute2WayPartitionParams(ctrl, graph);
+    /* printf("IPART: %3d [%5d %5d] [%5d %5d] %5d\n", graph->nvtxs, pwgts[0], pwgts[1], graph->pwgts[0], graph->pwgts[1], graph->mincut); */
+
+    Balance2Way(ctrl, graph, tpwgts, ubfactor);
+    /* printf("BPART: [%5d %5d] %5d\n", graph->pwgts[0], graph->pwgts[1], graph->mincut); */
+
+    FM_2WayEdgeRefine(ctrl, graph, tpwgts, 4);
+    /* printf("RPART: [%5d %5d] %5d\n", graph->pwgts[0], graph->pwgts[1], graph->mincut); */
+
+    if (bestcut > graph->mincut) {
+      bestcut = graph->mincut;
+      idxcopy(nvtxs, where, bestwhere);
+      if (bestcut == 0)
+        break;
+    }
+  }
+
+  graph->mincut = bestcut;
+  idxcopy(nvtxs, bestwhere, where);
+
+  GKfree(&bestwhere, &perm, LTERM);
+}
+
+
+
+
diff --git a/Metis/kmetis.c b/Metis/kmetis.c
new file mode 100644
index 0000000000..f684c1bbad
--- /dev/null
+++ b/Metis/kmetis.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * kmetis.c
+ *
+ * This file contains the top level routines for the multilevel k-way partitioning
+ * algorithm KMETIS.
+ *
+ * Started 7/28/97
+ * George
+ *
+ * $Id: kmetis.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function is the entry point for KMETIS
+**************************************************************************/
+void METIS_PartGraphKway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, 
+                         idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, 
+                         int *options, int *edgecut, idxtype *part)
+{
+  int i;
+  float *tpwgts;
+
+  tpwgts = fmalloc(*nparts, "KMETIS: tpwgts");
+  for (i=0; i<*nparts; i++) 
+    tpwgts[i] = 1.0/(1.0*(*nparts));
+
+  METIS_WPartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, 
+                       tpwgts, options, edgecut, part);
+
+  free(tpwgts);
+}
+
+
+/*************************************************************************
+* This function is the entry point for KWMETIS
+**************************************************************************/
+void METIS_WPartGraphKway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, 
+                          idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, 
+                          float *tpwgts, int *options, int *edgecut, idxtype *part)
+{
+  int i, j;
+  GraphType graph;
+  CtrlType ctrl;
+
+  if (*numflag == 1)
+    Change2CNumbering(*nvtxs, xadj, adjncy);
+
+  SetUpGraph(&graph, OP_KMETIS, *nvtxs, 1, xadj, adjncy, vwgt, adjwgt, *wgtflag);
+
+  if (options[0] == 0) {  /* Use the default parameters */
+    ctrl.CType = KMETIS_CTYPE;
+    ctrl.IType = KMETIS_ITYPE;
+    ctrl.RType = KMETIS_RTYPE;
+    ctrl.dbglvl = KMETIS_DBGLVL;
+  }
+  else {
+    ctrl.CType = options[OPTION_CTYPE];
+    ctrl.IType = options[OPTION_ITYPE];
+    ctrl.RType = options[OPTION_RTYPE];
+    ctrl.dbglvl = options[OPTION_DBGLVL];
+  }
+  ctrl.optype = OP_KMETIS;
+  ctrl.CoarsenTo = amax((*nvtxs)/(40*log2(*nparts)), 20*(*nparts));
+  ctrl.maxvwgt = 1.5*((graph.vwgt ? idxsum(*nvtxs, graph.vwgt) : (*nvtxs))/ctrl.CoarsenTo);
+
+  InitRandom(-1);
+
+  AllocateWorkSpace(&ctrl, &graph, *nparts);
+
+  IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl));
+  IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr));
+
+  *edgecut = MlevelKWayPartitioning(&ctrl, &graph, *nparts, part, tpwgts, 1.03);
+
+  IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr));
+  IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl));
+
+  FreeWorkSpace(&ctrl, &graph);
+
+  if (*numflag == 1)
+    Change2FNumbering(*nvtxs, xadj, adjncy, part);
+}
+
+
+/*************************************************************************
+* This function takes a graph and produces a bisection of it
+**************************************************************************/
+int MlevelKWayPartitioning(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, float *tpwgts, float ubfactor)
+{
+  int i, j, nvtxs, tvwgt, tpwgts2[2];
+  GraphType *cgraph;
+  int wgtflag=3, numflag=0, options[10], edgecut;
+
+  cgraph = Coarsen2Way(ctrl, graph);
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr));
+  AllocateKWayPartitionMemory(ctrl, cgraph, nparts);
+
+  options[0] = 1; 
+  options[OPTION_CTYPE] = MATCH_SHEMKWAY;
+  options[OPTION_ITYPE] = IPART_GGPKL;
+  options[OPTION_RTYPE] = RTYPE_FM;
+  options[OPTION_DBGLVL] = 0;
+
+  METIS_WPartGraphRecursive(&cgraph->nvtxs, cgraph->xadj, cgraph->adjncy, cgraph->vwgt, 
+                            cgraph->adjwgt, &wgtflag, &numflag, &nparts, tpwgts, options, 
+                            &edgecut, cgraph->where);
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr));
+  IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial %d-way partitioning cut: %d\n", nparts, edgecut));
+
+  IFSET(ctrl->dbglvl, DBG_KWAYPINFO, ComputePartitionInfo(cgraph, nparts, cgraph->where));
+
+  RefineKWay(ctrl, graph, cgraph, nparts, tpwgts, ubfactor);
+
+  idxcopy(graph->nvtxs, graph->where, part);
+
+  GKfree(&graph->gdata, &graph->rdata, LTERM);
+
+  return graph->mincut;
+
+}
+
diff --git a/Metis/kvmetis.c b/Metis/kvmetis.c
new file mode 100644
index 0000000000..6cb7f17b18
--- /dev/null
+++ b/Metis/kvmetis.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * kvmetis.c
+ *
+ * This file contains the top level routines for the multilevel k-way partitioning
+ * algorithm KMETIS.
+ *
+ * Started 7/28/97
+ * George
+ *
+ * $Id: kvmetis.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function is the entry point for KMETIS
+**************************************************************************/
+void METIS_PartGraphVKway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, 
+                         idxtype *vsize, int *wgtflag, int *numflag, int *nparts, 
+                         int *options, int *volume, idxtype *part)
+{
+  int i;
+  float *tpwgts;
+
+  tpwgts = fmalloc(*nparts, "KMETIS: tpwgts");
+  for (i=0; i<*nparts; i++) 
+    tpwgts[i] = 1.0/(1.0*(*nparts));
+
+  METIS_WPartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, 
+                       tpwgts, options, volume, part);
+
+  free(tpwgts);
+}
+
+
+/*************************************************************************
+* This function is the entry point for KWMETIS
+**************************************************************************/
+void METIS_WPartGraphVKway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, 
+                          idxtype *vsize, int *wgtflag, int *numflag, int *nparts, 
+                          float *tpwgts, int *options, int *volume, idxtype *part)
+{
+  int i, j;
+  GraphType graph;
+  CtrlType ctrl;
+
+  if (*numflag == 1)
+    Change2CNumbering(*nvtxs, xadj, adjncy);
+
+  VolSetUpGraph(&graph, OP_KVMETIS, *nvtxs, 1, xadj, adjncy, vwgt, vsize, *wgtflag);
+
+  if (options[0] == 0) {  /* Use the default parameters */
+    ctrl.CType = KVMETIS_CTYPE;
+    ctrl.IType = KVMETIS_ITYPE;
+    ctrl.RType = KVMETIS_RTYPE;
+    ctrl.dbglvl = KVMETIS_DBGLVL;
+  }
+  else {
+    ctrl.CType = options[OPTION_CTYPE];
+    ctrl.IType = options[OPTION_ITYPE];
+    ctrl.RType = options[OPTION_RTYPE];
+    ctrl.dbglvl = options[OPTION_DBGLVL];
+  }
+  ctrl.optype = OP_KVMETIS;
+  ctrl.CoarsenTo = amax((*nvtxs)/(40*log2(*nparts)), 20*(*nparts));
+  ctrl.maxvwgt = 1.5*((graph.vwgt ? idxsum(*nvtxs, graph.vwgt) : (*nvtxs))/ctrl.CoarsenTo);
+
+  InitRandom(-1);
+
+  AllocateWorkSpace(&ctrl, &graph, *nparts);
+
+  IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl));
+  IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr));
+
+  *volume = MlevelVolKWayPartitioning(&ctrl, &graph, *nparts, part, tpwgts, 1.03);
+
+  IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr));
+  IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl));
+
+  FreeWorkSpace(&ctrl, &graph);
+
+  if (*numflag == 1)
+    Change2FNumbering(*nvtxs, xadj, adjncy, part);
+}
+
+
+/*************************************************************************
+* This function takes a graph and produces a bisection of it
+**************************************************************************/
+int MlevelVolKWayPartitioning(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, 
+                              float *tpwgts, float ubfactor)
+{
+  int i, j, nvtxs, tvwgt, tpwgts2[2];
+  GraphType *cgraph;
+  int wgtflag=3, numflag=0, options[10], edgecut;
+
+  cgraph = Coarsen2Way(ctrl, graph);
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr));
+  AllocateVolKWayPartitionMemory(ctrl, cgraph, nparts);
+
+  options[0] = 1; 
+  options[OPTION_CTYPE] = MATCH_SHEMKWAY;
+  options[OPTION_ITYPE] = IPART_GGPKL;
+  options[OPTION_RTYPE] = RTYPE_FM;
+  options[OPTION_DBGLVL] = 0;
+
+  METIS_WPartGraphRecursive(&cgraph->nvtxs, cgraph->xadj, cgraph->adjncy, cgraph->vwgt, 
+                            cgraph->adjwgt, &wgtflag, &numflag, &nparts, tpwgts, options, 
+                            &edgecut, cgraph->where);
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr));
+  IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial %d-way partitioning cut: %d\n", nparts, edgecut));
+
+  IFSET(ctrl->dbglvl, DBG_KWAYPINFO, ComputePartitionInfo(cgraph, nparts, cgraph->where));
+
+  RefineVolKWay(ctrl, graph, cgraph, nparts, tpwgts, ubfactor);
+
+  idxcopy(graph->nvtxs, graph->where, part);
+
+  GKfree(&graph->gdata, &graph->rdata, LTERM);
+
+  return graph->minvol;
+
+}
+
diff --git a/Metis/kwayfm.c b/Metis/kwayfm.c
new file mode 100644
index 0000000000..5b376e5db3
--- /dev/null
+++ b/Metis/kwayfm.c
@@ -0,0 +1,672 @@
+/*
+ * kwayfm.c
+ *
+ * This file contains code that implements the multilevel k-way refinement
+ *
+ * Started 7/28/97
+ * George
+ *
+ * $Id: kwayfm.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function performs k-way refinement
+**************************************************************************/
+void Random_KWayEdgeRefine(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses, int ffactor)
+{
+  int i, ii, iii, j, jj, k, l, pass, nvtxs, nmoves, nbnd, tvwgt, myndegrees; 
+  int from, me, to, oldcut, vwgt, gain;
+  idxtype *xadj, *adjncy, *adjwgt;
+  idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts;
+  EDegreeType *myedegrees;
+  RInfoType *myrinfo;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+
+  where = graph->where;
+  pwgts = graph->pwgts;
+  
+  /* Setup the weight intervals of the various subdomains */
+  minwgt =  idxwspacemalloc(ctrl, nparts);
+  maxwgt = idxwspacemalloc(ctrl, nparts);
+  itpwgts = idxwspacemalloc(ctrl, nparts);
+  tvwgt = idxsum(nparts, pwgts);
+  ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt));
+
+  for (i=0; i<nparts; i++) {
+    itpwgts[i] = tpwgts[i]*tvwgt;
+    maxwgt[i] = tpwgts[i]*tvwgt*ubfactor;
+    minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor);
+  }
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+
+  IFSET(ctrl->dbglvl, DBG_REFINE,
+     printf("Partitions: [%6d %6d]-[%6d %6d], Balance: %5.3f, Nv-Nb[%6d %6d]. Cut: %6d\n",
+             pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], 
+             1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd,
+             graph->mincut));
+
+  for (pass=0; pass<npasses; pass++) {
+    ASSERT(ComputeCut(graph, where) == graph->mincut);
+
+    oldcut = graph->mincut;
+    nbnd = graph->nbnd;
+
+    RandomPermute(nbnd, perm, 1);
+    for (nmoves=iii=0; iii<graph->nbnd; iii++) {
+      ii = perm[iii];
+      if (ii >= nbnd)
+        continue;
+      i = bndind[ii];
+
+      myrinfo = graph->rinfo+i;
+
+      if (myrinfo->ed >= myrinfo->id) { /* Total ED is too high */
+        from = where[i];
+        vwgt = graph->vwgt[i];
+
+        if (myrinfo->id > 0 && pwgts[from]-vwgt < minwgt[from]) 
+          continue;   /* This cannot be moved! */
+
+        myedegrees = myrinfo->edegrees;
+        myndegrees = myrinfo->ndegrees;
+
+        j = myrinfo->id;
+        for (k=0; k<myndegrees; k++) {
+          to = myedegrees[k].pid;
+          gain = myedegrees[k].ed-j; /* j = myrinfo->id. Allow good nodes to move */ 
+          if (pwgts[to]+vwgt <= maxwgt[to]+ffactor*gain && gain >= 0)  
+            break;
+        }
+        if (k == myndegrees)
+          continue;  /* break out if you did not find a candidate */
+
+        for (j=k+1; j<myndegrees; j++) {
+          to = myedegrees[j].pid;
+          if ((myedegrees[j].ed > myedegrees[k].ed && pwgts[to]+vwgt <= maxwgt[to]) ||
+              (myedegrees[j].ed == myedegrees[k].ed && 
+               itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid]))
+            k = j;
+        }
+
+        to = myedegrees[k].pid;
+
+        j = 0;
+        if (myedegrees[k].ed-myrinfo->id > 0)
+          j = 1;
+        else if (myedegrees[k].ed-myrinfo->id == 0) {
+          if ((iii&7) == 0 || pwgts[from] >= maxwgt[from] || itpwgts[from]*(pwgts[to]+vwgt) < itpwgts[to]*pwgts[from])
+            j = 1;
+        }
+        if (j == 0)
+          continue;
+          
+        /*=====================================================================
+        * If we got here, we can now move the vertex from 'from' to 'to' 
+        *======================================================================*/
+        graph->mincut -= myedegrees[k].ed-myrinfo->id;
+
+        IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut));
+
+        /* Update where, weight, and ID/ED information of the vertex you moved */
+        where[i] = to;
+        INC_DEC(pwgts[to], pwgts[from], vwgt);
+        myrinfo->ed += myrinfo->id-myedegrees[k].ed;
+        SWAP(myrinfo->id, myedegrees[k].ed, j);
+        if (myedegrees[k].ed == 0) 
+          myedegrees[k] = myedegrees[--myrinfo->ndegrees];
+        else
+          myedegrees[k].pid = from;
+
+        if (myrinfo->ed-myrinfo->id < 0)
+          BNDDelete(nbnd, bndind, bndptr, i);
+
+        /* Update the degrees of adjacent vertices */
+        for (j=xadj[i]; j<xadj[i+1]; j++) {
+          ii = adjncy[j];
+          me = where[ii];
+
+          myrinfo = graph->rinfo+ii;
+          if (myrinfo->edegrees == NULL) {
+            myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree;
+            ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii];
+          }
+          myedegrees = myrinfo->edegrees;
+
+          ASSERT(CheckRInfo(myrinfo));
+
+          if (me == from) {
+            INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]);
+
+            if (myrinfo->ed-myrinfo->id >= 0 && bndptr[ii] == -1)
+              BNDInsert(nbnd, bndind, bndptr, ii);
+          }
+          else if (me == to) {
+            INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]);
+
+            if (myrinfo->ed-myrinfo->id < 0 && bndptr[ii] != -1)
+              BNDDelete(nbnd, bndind, bndptr, ii);
+          }
+
+          /* Remove contribution from the .ed of 'from' */
+          if (me != from) {
+            for (k=0; k<myrinfo->ndegrees; k++) {
+              if (myedegrees[k].pid == from) {
+                if (myedegrees[k].ed == adjwgt[j])
+                  myedegrees[k] = myedegrees[--myrinfo->ndegrees];
+                else
+                  myedegrees[k].ed -= adjwgt[j];
+                break;
+              }
+            }
+          }
+
+          /* Add contribution to the .ed of 'to' */
+          if (me != to) {
+            for (k=0; k<myrinfo->ndegrees; k++) {
+              if (myedegrees[k].pid == to) {
+                myedegrees[k].ed += adjwgt[j];
+                break;
+              }
+            }
+            if (k == myrinfo->ndegrees) {
+              myedegrees[myrinfo->ndegrees].pid = to;
+              myedegrees[myrinfo->ndegrees++].ed = adjwgt[j];
+            }
+          }
+
+          ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]);
+          ASSERT(CheckRInfo(myrinfo));
+
+        }
+        nmoves++;
+      }
+    }
+
+    graph->nbnd = nbnd;
+
+    IFSET(ctrl->dbglvl, DBG_REFINE,
+       printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, Vol: %6d\n",
+               pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)],
+               1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, graph->mincut, ComputeVolume(graph, where)));
+
+    if (graph->mincut == oldcut)
+      break;
+  }
+
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+
+
+
+
+/*************************************************************************
+* This function performs k-way refinement
+**************************************************************************/
+void Greedy_KWayEdgeRefine(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses)
+{
+  int i, ii, iii, j, jj, k, l, pass, nvtxs, nbnd, tvwgt, myndegrees, oldgain, gain; 
+  int from, me, to, oldcut, vwgt;
+  idxtype *xadj, *adjncy, *adjwgt;
+  idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *moved, *itpwgts;
+  EDegreeType *myedegrees;
+  RInfoType *myrinfo;
+  PQueueType queue;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  bndind = graph->bndind;
+  bndptr = graph->bndptr;
+
+  where = graph->where;
+  pwgts = graph->pwgts;
+  
+  /* Setup the weight intervals of the various subdomains */
+  minwgt =  idxwspacemalloc(ctrl, nparts);
+  maxwgt = idxwspacemalloc(ctrl, nparts);
+  itpwgts = idxwspacemalloc(ctrl, nparts);
+  tvwgt = idxsum(nparts, pwgts);
+  ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt));
+
+  for (i=0; i<nparts; i++) {
+    itpwgts[i] = tpwgts[i]*tvwgt;
+    maxwgt[i] = tpwgts[i]*tvwgt*ubfactor;
+    minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor);
+  }
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  moved = idxwspacemalloc(ctrl, nvtxs);
+
+  PQueueInit(ctrl, &queue, nvtxs, graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]);
+
+  IFSET(ctrl->dbglvl, DBG_REFINE,
+     printf("Partitions: [%6d %6d]-[%6d %6d], Balance: %5.3f, Nv-Nb[%6d %6d]. Cut: %6d\n",
+             pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], 
+             1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd,
+             graph->mincut));
+
+  for (pass=0; pass<npasses; pass++) {
+    ASSERT(ComputeCut(graph, where) == graph->mincut);
+
+    PQueueReset(&queue);
+    idxset(nvtxs, -1, moved);
+
+    oldcut = graph->mincut;
+    nbnd = graph->nbnd;
+
+    RandomPermute(nbnd, perm, 1);
+    for (ii=0; ii<nbnd; ii++) {
+      i = bndind[perm[ii]];
+      PQueueInsert(&queue, i, graph->rinfo[i].ed - graph->rinfo[i].id);
+      moved[i] = 2;
+    }
+
+    for (iii=0;;iii++) {
+      if ((i = PQueueGetMax(&queue)) == -1) 
+        break;
+      moved[i] = 1;
+
+      myrinfo = graph->rinfo+i;
+      from = where[i];
+      vwgt = graph->vwgt[i];
+
+      if (pwgts[from]-vwgt < minwgt[from]) 
+        continue;   /* This cannot be moved! */
+
+      myedegrees = myrinfo->edegrees;
+      myndegrees = myrinfo->ndegrees;
+
+      j = myrinfo->id;
+      for (k=0; k<myndegrees; k++) {
+        to = myedegrees[k].pid;
+        gain = myedegrees[k].ed-j; /* j = myrinfo->id. Allow good nodes to move */ 
+        if (pwgts[to]+vwgt <= maxwgt[to]+gain && gain >= 0)  
+          break;
+      }
+      if (k == myndegrees)
+        continue;  /* break out if you did not find a candidate */
+
+      for (j=k+1; j<myndegrees; j++) {
+        to = myedegrees[j].pid;
+        if ((myedegrees[j].ed > myedegrees[k].ed && pwgts[to]+vwgt <= maxwgt[to]) ||
+            (myedegrees[j].ed == myedegrees[k].ed && 
+             itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid]))
+          k = j;
+      }
+
+      to = myedegrees[k].pid;
+
+      j = 0;
+      if (myedegrees[k].ed-myrinfo->id > 0)
+        j = 1;
+      else if (myedegrees[k].ed-myrinfo->id == 0) {
+        if ((iii&7) == 0 || pwgts[from] >= maxwgt[from] || itpwgts[from]*(pwgts[to]+vwgt) < itpwgts[to]*pwgts[from])
+          j = 1;
+      }
+      if (j == 0)
+        continue;
+          
+      /*=====================================================================
+      * If we got here, we can now move the vertex from 'from' to 'to' 
+      *======================================================================*/
+      graph->mincut -= myedegrees[k].ed-myrinfo->id;
+
+      IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut));
+
+      /* Update where, weight, and ID/ED information of the vertex you moved */
+      where[i] = to;
+      INC_DEC(pwgts[to], pwgts[from], vwgt);
+      myrinfo->ed += myrinfo->id-myedegrees[k].ed;
+      SWAP(myrinfo->id, myedegrees[k].ed, j);
+      if (myedegrees[k].ed == 0) 
+        myedegrees[k] = myedegrees[--myrinfo->ndegrees];
+      else
+        myedegrees[k].pid = from;
+
+      if (myrinfo->ed < myrinfo->id)
+        BNDDelete(nbnd, bndind, bndptr, i);
+
+      /* Update the degrees of adjacent vertices */
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        ii = adjncy[j];
+        me = where[ii];
+
+        myrinfo = graph->rinfo+ii;
+        if (myrinfo->edegrees == NULL) {
+          myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree;
+          ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii];
+        }
+        myedegrees = myrinfo->edegrees;
+
+        ASSERT(CheckRInfo(myrinfo));
+
+        oldgain = (myrinfo->ed-myrinfo->id);
+
+        if (me == from) {
+          INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]);
+
+          if (myrinfo->ed-myrinfo->id >= 0 && bndptr[ii] == -1)
+            BNDInsert(nbnd, bndind, bndptr, ii);
+        }
+        else if (me == to) {
+          INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]);
+
+          if (myrinfo->ed-myrinfo->id < 0 && bndptr[ii] != -1)
+            BNDDelete(nbnd, bndind, bndptr, ii);
+        }
+
+        /* Remove contribution from the .ed of 'from' */
+        if (me != from) {
+          for (k=0; k<myrinfo->ndegrees; k++) {
+            if (myedegrees[k].pid == from) {
+              if (myedegrees[k].ed == adjwgt[j])
+                myedegrees[k] = myedegrees[--myrinfo->ndegrees];
+              else
+                myedegrees[k].ed -= adjwgt[j];
+              break;
+            }
+          }
+        }
+
+        /* Add contribution to the .ed of 'to' */
+        if (me != to) {
+          for (k=0; k<myrinfo->ndegrees; k++) {
+            if (myedegrees[k].pid == to) {
+              myedegrees[k].ed += adjwgt[j];
+              break;
+            }
+          }
+          if (k == myrinfo->ndegrees) {
+            myedegrees[myrinfo->ndegrees].pid = to;
+            myedegrees[myrinfo->ndegrees++].ed = adjwgt[j];
+          }
+        }
+
+        /* Update the queue */
+        if (me == to || me == from) { 
+          gain = myrinfo->ed-myrinfo->id;
+          if (moved[ii] == 2) {
+            if (gain >= 0)
+              PQueueUpdate(&queue, ii, oldgain, gain);
+            else {
+              PQueueDelete(&queue, ii, oldgain);
+              moved[ii] = -1;
+            }
+          }
+          else if (moved[ii] == -1 && gain >= 0) {
+            PQueueInsert(&queue, ii, gain);
+            moved[ii] = 2;
+          }
+        } 
+
+        ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]);
+        ASSERT(CheckRInfo(myrinfo));
+
+      }
+    }
+
+    graph->nbnd = nbnd;
+
+    IFSET(ctrl->dbglvl, DBG_REFINE,
+       printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Cut: %6d\n",
+               pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)],
+               1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, graph->mincut));
+
+    if (graph->mincut == oldcut)
+      break;
+  }
+
+  PQueueFree(ctrl, &queue);
+
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+
+}
+
+
+/*************************************************************************
+* This function performs k-way refinement
+**************************************************************************/
+void Greedy_KWayEdgeBalance(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses)
+{
+  int i, ii, iii, j, jj, k, l, pass, nvtxs, nbnd, tvwgt, myndegrees, oldgain, gain, nmoves; 
+  int from, me, to, oldcut, vwgt;
+  idxtype *xadj, *adjncy, *adjwgt;
+  idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *moved, *itpwgts;
+  EDegreeType *myedegrees;
+  RInfoType *myrinfo;
+  PQueueType queue;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  bndind = graph->bndind;
+  bndptr = graph->bndptr;
+
+  where = graph->where;
+  pwgts = graph->pwgts;
+  
+  /* Setup the weight intervals of the various subdomains */
+  minwgt =  idxwspacemalloc(ctrl, nparts);
+  maxwgt = idxwspacemalloc(ctrl, nparts);
+  itpwgts = idxwspacemalloc(ctrl, nparts);
+  tvwgt = idxsum(nparts, pwgts);
+  ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt));
+
+  for (i=0; i<nparts; i++) {
+    itpwgts[i] = tpwgts[i]*tvwgt;
+    maxwgt[i] = tpwgts[i]*tvwgt*ubfactor;
+    minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor);
+  }
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  moved = idxwspacemalloc(ctrl, nvtxs);
+
+  PQueueInit(ctrl, &queue, nvtxs, graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]);
+
+  IFSET(ctrl->dbglvl, DBG_REFINE,
+     printf("Partitions: [%6d %6d]-[%6d %6d], Balance: %5.3f, Nv-Nb[%6d %6d]. Cut: %6d [B]\n",
+             pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], 
+             1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd,
+             graph->mincut));
+
+  for (pass=0; pass<npasses; pass++) {
+    ASSERT(ComputeCut(graph, where) == graph->mincut);
+
+    /* Check to see if things are out of balance, given the tolerance */
+    for (i=0; i<nparts; i++) {
+      if (pwgts[i] > maxwgt[i])
+        break;
+    }
+    if (i == nparts) /* Things are balanced. Return right away */
+      break;
+
+    PQueueReset(&queue);
+    idxset(nvtxs, -1, moved);
+
+    oldcut = graph->mincut;
+    nbnd = graph->nbnd;
+
+    RandomPermute(nbnd, perm, 1);
+    for (ii=0; ii<nbnd; ii++) {
+      i = bndind[perm[ii]];
+      PQueueInsert(&queue, i, graph->rinfo[i].ed - graph->rinfo[i].id);
+      moved[i] = 2;
+    }
+
+    nmoves = 0;
+    for (;;) {
+      if ((i = PQueueGetMax(&queue)) == -1) 
+        break;
+      moved[i] = 1;
+
+      myrinfo = graph->rinfo+i;
+      from = where[i];
+      vwgt = graph->vwgt[i];
+
+      if (pwgts[from]-vwgt < minwgt[from]) 
+        continue;   /* This cannot be moved! */
+
+      myedegrees = myrinfo->edegrees;
+      myndegrees = myrinfo->ndegrees;
+
+      for (k=0; k<myndegrees; k++) {
+        to = myedegrees[k].pid;
+        if (pwgts[to]+vwgt <= maxwgt[to] || itpwgts[from]*(pwgts[to]+vwgt) <= itpwgts[to]*pwgts[from]) 
+          break;
+      }
+      if (k == myndegrees)
+        continue;  /* break out if you did not find a candidate */
+
+      for (j=k+1; j<myndegrees; j++) {
+        to = myedegrees[j].pid;
+        if (itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid]) 
+          k = j;
+      }
+
+      to = myedegrees[k].pid;
+
+      if (pwgts[from] < maxwgt[from] && pwgts[to] > minwgt[to] && myedegrees[k].ed-myrinfo->id < 0) 
+        continue;
+
+      /*=====================================================================
+      * If we got here, we can now move the vertex from 'from' to 'to' 
+      *======================================================================*/
+      graph->mincut -= myedegrees[k].ed-myrinfo->id;
+
+      IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut));
+
+      /* Update where, weight, and ID/ED information of the vertex you moved */
+      where[i] = to;
+      INC_DEC(pwgts[to], pwgts[from], vwgt);
+      myrinfo->ed += myrinfo->id-myedegrees[k].ed;
+      SWAP(myrinfo->id, myedegrees[k].ed, j);
+      if (myedegrees[k].ed == 0) 
+        myedegrees[k] = myedegrees[--myrinfo->ndegrees];
+      else
+        myedegrees[k].pid = from;
+
+      if (myrinfo->ed == 0)
+        BNDDelete(nbnd, bndind, bndptr, i);
+
+      /* Update the degrees of adjacent vertices */
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        ii = adjncy[j];
+        me = where[ii];
+
+        myrinfo = graph->rinfo+ii;
+        if (myrinfo->edegrees == NULL) {
+          myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree;
+          ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii];
+        }
+        myedegrees = myrinfo->edegrees;
+
+        ASSERT(CheckRInfo(myrinfo));
+
+        oldgain = (myrinfo->ed-myrinfo->id);
+
+        if (me == from) {
+          INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]);
+
+          if (myrinfo->ed > 0 && bndptr[ii] == -1)
+            BNDInsert(nbnd, bndind, bndptr, ii);
+        }
+        else if (me == to) {
+          INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]);
+
+          if (myrinfo->ed == 0 && bndptr[ii] != -1)
+            BNDDelete(nbnd, bndind, bndptr, ii);
+        }
+
+        /* Remove contribution from the .ed of 'from' */
+        if (me != from) {
+          for (k=0; k<myrinfo->ndegrees; k++) {
+            if (myedegrees[k].pid == from) {
+              if (myedegrees[k].ed == adjwgt[j])
+                myedegrees[k] = myedegrees[--myrinfo->ndegrees];
+              else
+                myedegrees[k].ed -= adjwgt[j];
+              break;
+            }
+          }
+        }
+
+        /* Add contribution to the .ed of 'to' */
+        if (me != to) {
+          for (k=0; k<myrinfo->ndegrees; k++) {
+            if (myedegrees[k].pid == to) {
+              myedegrees[k].ed += adjwgt[j];
+              break;
+            }
+          }
+          if (k == myrinfo->ndegrees) {
+            myedegrees[myrinfo->ndegrees].pid = to;
+            myedegrees[myrinfo->ndegrees++].ed = adjwgt[j];
+          }
+        }
+
+        /* Update the queue */
+        if (me == to || me == from) { 
+          gain = myrinfo->ed-myrinfo->id;
+          if (moved[ii] == 2) {
+            if (myrinfo->ed > 0)
+              PQueueUpdate(&queue, ii, oldgain, gain);
+            else {
+              PQueueDelete(&queue, ii, oldgain);
+              moved[ii] = -1;
+            }
+          }
+          else if (moved[ii] == -1 && myrinfo->ed > 0) {
+            PQueueInsert(&queue, ii, gain);
+            moved[ii] = 2;
+          }
+        } 
+
+        ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]);
+        ASSERT(CheckRInfo(myrinfo));
+      }
+      nmoves++;
+    }
+
+    graph->nbnd = nbnd;
+
+    IFSET(ctrl->dbglvl, DBG_REFINE,
+       printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d\n",
+               pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)],
+               1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, graph->mincut));
+  }
+
+  PQueueFree(ctrl, &queue);
+
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+
+}
+
diff --git a/Metis/kwayrefine.c b/Metis/kwayrefine.c
new file mode 100644
index 0000000000..8a9ff04008
--- /dev/null
+++ b/Metis/kwayrefine.c
@@ -0,0 +1,392 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * kwayrefine.c
+ *
+ * This file contains the driving routines for multilevel k-way refinement
+ *
+ * Started 7/28/97
+ * George
+ *
+ * $Id: kwayrefine.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function is the entry point of refinement
+**************************************************************************/
+void RefineKWay(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, int nparts, float *tpwgts, float ubfactor)
+{
+  int i, nlevels, mustfree=0;
+  GraphType *ptr;
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr));
+
+  /* Compute the parameters of the coarsest graph */
+  ComputeKWayPartitionParams(ctrl, graph, nparts);
+
+  /* Take care any non-contiguity */
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->AuxTmr1));
+  if (ctrl->RType == RTYPE_KWAYRANDOM_MCONN) {
+    EliminateComponents(ctrl, graph, nparts, tpwgts, 1.25);
+    EliminateSubDomainEdges(ctrl, graph, nparts, tpwgts);
+    EliminateComponents(ctrl, graph, nparts, tpwgts, 1.25);
+  }
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->AuxTmr1));
+
+  /* Determine how many levels are there */
+  for (ptr=graph, nlevels=0; ptr!=orggraph; ptr=ptr->finer, nlevels++); 
+
+  for (i=0; ;i++) {
+    /* PrintSubDomainGraph(graph, nparts, graph->where); */
+    if (ctrl->RType == RTYPE_KWAYRANDOM_MCONN && (i == nlevels/2 || i == nlevels/2+1))
+      EliminateSubDomainEdges(ctrl, graph, nparts, tpwgts);
+
+    IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr));
+
+    if (2*i >= nlevels && !IsBalanced(graph->pwgts, nparts, tpwgts, 1.04*ubfactor)) {
+      ComputeKWayBalanceBoundary(ctrl, graph, nparts);
+      if (ctrl->RType == RTYPE_KWAYRANDOM_MCONN)
+        Greedy_KWayEdgeBalanceMConn(ctrl, graph, nparts, tpwgts, ubfactor, 1); 
+      else
+        Greedy_KWayEdgeBalance(ctrl, graph, nparts, tpwgts, ubfactor, 1); 
+      ComputeKWayBoundary(ctrl, graph, nparts);
+    }
+
+    switch (ctrl->RType) {
+      case RTYPE_KWAYRANDOM:
+        Random_KWayEdgeRefine(ctrl, graph, nparts, tpwgts, ubfactor, 10, 1); 
+        break;
+      case RTYPE_KWAYGREEDY:
+        Greedy_KWayEdgeRefine(ctrl, graph, nparts, tpwgts, ubfactor, 10); 
+        break;
+      case RTYPE_KWAYRANDOM_MCONN:
+        Random_KWayEdgeRefineMConn(ctrl, graph, nparts, tpwgts, ubfactor, 10, 1); 
+        break;
+    }
+    IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr));
+
+    if (graph == orggraph)
+      break;
+
+    GKfree(&graph->gdata, LTERM);  /* Deallocate the graph related arrays */
+
+    graph = graph->finer;
+
+    IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr));
+    if (graph->vwgt == NULL) {
+      graph->vwgt = idxsmalloc(graph->nvtxs, 1, "RefineKWay: graph->vwgt");
+      graph->adjwgt = idxsmalloc(graph->nedges, 1, "RefineKWay: graph->adjwgt");
+      mustfree = 1;
+    }
+    ProjectKWayPartition(ctrl, graph, nparts);
+    IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr));
+  }
+
+  if (!IsBalanced(graph->pwgts, nparts, tpwgts, ubfactor)) {
+    ComputeKWayBalanceBoundary(ctrl, graph, nparts);
+    if (ctrl->RType == RTYPE_KWAYRANDOM_MCONN) {
+      Greedy_KWayEdgeBalanceMConn(ctrl, graph, nparts, tpwgts, ubfactor, 8); 
+      Random_KWayEdgeRefineMConn(ctrl, graph, nparts, tpwgts, ubfactor, 10, 0); 
+    }
+    else {
+      Greedy_KWayEdgeBalance(ctrl, graph, nparts, tpwgts, ubfactor, 8); 
+      Random_KWayEdgeRefine(ctrl, graph, nparts, tpwgts, ubfactor, 10, 0); 
+    }
+  }
+
+  /* Take care any trivial non-contiguity */
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->AuxTmr2));
+  EliminateComponents(ctrl, graph, nparts, tpwgts, ubfactor);
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->AuxTmr2));
+
+  if (mustfree) 
+    GKfree(&graph->vwgt, &graph->adjwgt, LTERM);
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr));
+}
+
+
+/*************************************************************************
+* This function allocates memory for k-way edge refinement
+**************************************************************************/
+void AllocateKWayPartitionMemory(CtrlType *ctrl, GraphType *graph, int nparts)
+{
+  int nvtxs, pad64;
+
+  nvtxs = graph->nvtxs;
+
+  pad64 = (3*nvtxs+nparts)%2;
+
+  graph->rdata = idxmalloc(3*nvtxs+nparts+(sizeof(RInfoType)/sizeof(idxtype))*nvtxs+pad64, "AllocateKWayPartitionMemory: rdata");
+  graph->pwgts          = graph->rdata;
+  graph->where          = graph->rdata + nparts;
+  graph->bndptr         = graph->rdata + nvtxs + nparts;
+  graph->bndind         = graph->rdata + 2*nvtxs + nparts;
+  graph->rinfo          = (RInfoType *)(graph->rdata + 3*nvtxs+nparts + pad64);
+
+/*
+  if (ctrl->wspace.edegrees != NULL)
+    free(ctrl->wspace.edegrees);
+  ctrl->wspace.edegrees = (EDegreeType *)GKmalloc(graph->nedges*sizeof(EDegreeType), "AllocateKWayPartitionMemory: edegrees");
+*/
+}
+
+
+/*************************************************************************
+* This function computes the initial id/ed 
+**************************************************************************/
+void ComputeKWayPartitionParams(CtrlType *ctrl, GraphType *graph, int nparts)
+{
+  int i, j, k, l, nvtxs, nbnd, mincut, me, other;
+  idxtype *xadj, *vwgt, *adjncy, *adjwgt, *pwgts, *where, *bndind, *bndptr;
+  RInfoType *rinfo, *myrinfo;
+  EDegreeType *myedegrees;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  vwgt = graph->vwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  where = graph->where;
+  pwgts = idxset(nparts, 0, graph->pwgts);
+  bndind = graph->bndind;
+  bndptr = idxset(nvtxs, -1, graph->bndptr);
+  rinfo = graph->rinfo;
+
+
+  /*------------------------------------------------------------
+  / Compute now the id/ed degrees
+  /------------------------------------------------------------*/
+  ctrl->wspace.cdegree = 0;
+  nbnd = mincut = 0;
+  for (i=0; i<nvtxs; i++) {
+    me = where[i];
+    pwgts[me] += vwgt[i];
+
+    myrinfo = rinfo+i;
+    myrinfo->id = myrinfo->ed = myrinfo->ndegrees = 0;
+    myrinfo->edegrees = NULL;
+
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      if (me != where[adjncy[j]])
+        myrinfo->ed += adjwgt[j];
+    }
+    myrinfo->id = graph->adjwgtsum[i] - myrinfo->ed;
+
+    if (myrinfo->ed > 0) 
+      mincut += myrinfo->ed;
+
+    if (myrinfo->ed-myrinfo->id >= 0)
+      BNDInsert(nbnd, bndind, bndptr, i);
+
+    /* Time to compute the particular external degrees */
+    if (myrinfo->ed > 0) { 
+      myedegrees = myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree;
+      ctrl->wspace.cdegree += xadj[i+1]-xadj[i];
+
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        other = where[adjncy[j]];
+        if (me != other) {
+          for (k=0; k<myrinfo->ndegrees; k++) {
+            if (myedegrees[k].pid == other) {
+              myedegrees[k].ed += adjwgt[j];
+              break;
+            }
+          }
+          if (k == myrinfo->ndegrees) {
+            myedegrees[myrinfo->ndegrees].pid = other;
+            myedegrees[myrinfo->ndegrees++].ed = adjwgt[j];
+          }
+        }
+      }
+
+      ASSERT(myrinfo->ndegrees <= xadj[i+1]-xadj[i]);
+    }
+  }
+
+  graph->mincut = mincut/2;
+  graph->nbnd = nbnd;
+
+}
+
+
+
+/*************************************************************************
+* This function projects a partition, and at the same time computes the
+* parameters for refinement.
+**************************************************************************/
+void ProjectKWayPartition(CtrlType *ctrl, GraphType *graph, int nparts)
+{
+  int i, j, k, nvtxs, nbnd, me, other, istart, iend, ndegrees;
+  idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum;
+  idxtype *cmap, *where, *bndptr, *bndind;
+  idxtype *cwhere;
+  GraphType *cgraph;
+  RInfoType *crinfo, *rinfo, *myrinfo;
+  EDegreeType *myedegrees;
+  idxtype *htable;
+
+  cgraph = graph->coarser;
+  cwhere = cgraph->where;
+  crinfo = cgraph->rinfo;
+
+  nvtxs = graph->nvtxs;
+  cmap = graph->cmap;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+  adjwgtsum = graph->adjwgtsum;
+
+  AllocateKWayPartitionMemory(ctrl, graph, nparts);
+  where = graph->where;
+  rinfo = graph->rinfo;
+  bndind = graph->bndind;
+  bndptr = idxset(nvtxs, -1, graph->bndptr);
+
+  /* Go through and project partition and compute id/ed for the nodes */
+  for (i=0; i<nvtxs; i++) {
+    k = cmap[i];
+    where[i] = cwhere[k];
+    cmap[i] = crinfo[k].ed;  /* For optimization */
+  }
+
+  htable = idxset(nparts, -1, idxwspacemalloc(ctrl, nparts));
+
+  ctrl->wspace.cdegree = 0;
+  for (nbnd=0, i=0; i<nvtxs; i++) {
+    me = where[i];
+
+    myrinfo = rinfo+i;
+    myrinfo->id = myrinfo->ed = myrinfo->ndegrees = 0;
+    myrinfo->edegrees = NULL;
+
+    myrinfo->id = adjwgtsum[i];
+
+    if (cmap[i] > 0) { /* If it is an interface node. Note cmap[i] = crinfo[cmap[i]].ed */
+      istart = xadj[i];
+      iend = xadj[i+1];
+
+      myedegrees = myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree;
+      ctrl->wspace.cdegree += iend-istart;
+
+      ndegrees = 0;
+      for (j=istart; j<iend; j++) {
+        other = where[adjncy[j]];
+        if (me != other) {
+          myrinfo->ed += adjwgt[j];
+          if ((k = htable[other]) == -1) {
+            htable[other] = ndegrees;
+            myedegrees[ndegrees].pid = other;
+            myedegrees[ndegrees++].ed = adjwgt[j];
+          }
+          else {
+            myedegrees[k].ed += adjwgt[j];
+          }
+        }
+      }
+      myrinfo->id -= myrinfo->ed;
+
+      /* Remove space for edegrees if it was interior */
+      if (myrinfo->ed == 0) { 
+        myrinfo->edegrees = NULL;
+        ctrl->wspace.cdegree -= iend-istart;
+      }
+      else {
+        if (myrinfo->ed-myrinfo->id >= 0) 
+          BNDInsert(nbnd, bndind, bndptr, i); 
+
+        myrinfo->ndegrees = ndegrees;
+
+        for (j=0; j<ndegrees; j++)
+          htable[myedegrees[j].pid] = -1;
+      }
+    }
+  }
+
+  idxcopy(nparts, cgraph->pwgts, graph->pwgts);
+  graph->mincut = cgraph->mincut;
+  graph->nbnd = nbnd;
+
+  FreeGraph(graph->coarser);
+  graph->coarser = NULL;
+
+  idxwspacefree(ctrl, nparts);
+
+  ASSERT(CheckBnd2(graph));
+
+}
+
+
+
+/*************************************************************************
+* This function checks if the partition weights are within the balance
+* contraints
+**************************************************************************/
+int IsBalanced(idxtype *pwgts, int nparts, float *tpwgts, float ubfactor)
+{
+  int i, j, tvwgt;
+
+  tvwgt = idxsum(nparts, pwgts);
+  for (i=0; i<nparts; i++) {
+    if (pwgts[i] > tpwgts[i]*tvwgt*(ubfactor+0.005))
+      return 0;
+  }
+
+  return 1;
+}
+
+
+/*************************************************************************
+* This function computes the boundary definition for balancing
+**************************************************************************/
+void ComputeKWayBoundary(CtrlType *ctrl, GraphType *graph, int nparts)
+{
+  int i, nvtxs, nbnd;
+  idxtype *bndind, *bndptr;
+
+  nvtxs = graph->nvtxs;
+  bndind = graph->bndind;
+  bndptr = idxset(nvtxs, -1, graph->bndptr);
+
+
+  /*------------------------------------------------------------
+  / Compute the new boundary
+  /------------------------------------------------------------*/
+  nbnd = 0;
+  for (i=0; i<nvtxs; i++) {
+    if (graph->rinfo[i].ed-graph->rinfo[i].id >= 0) 
+      BNDInsert(nbnd, bndind, bndptr, i);
+  }
+
+  graph->nbnd = nbnd;
+}
+
+/*************************************************************************
+* This function computes the boundary definition for balancing
+**************************************************************************/
+void ComputeKWayBalanceBoundary(CtrlType *ctrl, GraphType *graph, int nparts)
+{
+  int i, nvtxs, nbnd;
+  idxtype *bndind, *bndptr;
+
+  nvtxs = graph->nvtxs;
+  bndind = graph->bndind;
+  bndptr = idxset(nvtxs, -1, graph->bndptr);
+
+
+  /*------------------------------------------------------------
+  / Compute the new boundary
+  /------------------------------------------------------------*/
+  nbnd = 0;
+  for (i=0; i<nvtxs; i++) {
+    if (graph->rinfo[i].ed > 0) 
+      BNDInsert(nbnd, bndind, bndptr, i);
+  }
+
+  graph->nbnd = nbnd;
+}
+
diff --git a/Metis/kwayvolfm.c b/Metis/kwayvolfm.c
new file mode 100644
index 0000000000..16ce80b29a
--- /dev/null
+++ b/Metis/kwayvolfm.c
@@ -0,0 +1,1778 @@
+/*
+ * kwayvolfm.c
+ *
+ * This file contains code that implements the multilevel k-way refinement
+ *
+ * Started 7/8/98
+ * George
+ *
+ * $Id: kwayvolfm.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function performs k-way refinement
+**************************************************************************/
+void Random_KWayVolRefine(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, 
+                          float ubfactor, int npasses, int ffactor)
+{
+  int i, ii, iii, j, jj, k, kk, l, u, pass, nvtxs, nmoves, tvwgt, myndegrees, xgain; 
+  int from, me, to, oldcut, oldvol, vwgt;
+  idxtype *xadj, *adjncy, *adjwgt;
+  idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts, *updind, *marker, *phtable;
+  VEDegreeType *myedegrees;
+  VRInfoType *myrinfo; 
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+
+  where = graph->where;
+  pwgts = graph->pwgts;
+  
+  /* Setup the weight intervals of the various subdomains */
+  minwgt =  idxwspacemalloc(ctrl, nparts);
+  maxwgt = idxwspacemalloc(ctrl, nparts);
+  itpwgts = idxwspacemalloc(ctrl, nparts);
+  tvwgt = idxsum(nparts, pwgts);
+  ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt));
+
+  updind = idxmalloc(nvtxs, "Random_KWayVolRefine: updind");
+  marker = idxsmalloc(nvtxs, 0, "Random_KWayVolRefine: marker");
+  phtable = idxsmalloc(nparts, -1, "Random_KWayVolRefine: phtable");
+
+  for (i=0; i<nparts; i++) {
+    itpwgts[i] = tpwgts[i]*tvwgt;
+    maxwgt[i] = tpwgts[i]*tvwgt*ubfactor;
+    minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor);
+  }
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+
+  IFSET(ctrl->dbglvl, DBG_REFINE,
+     printf("VolPart: [%5d %5d]-[%5d %5d], Balance: %3.2f, Nv-Nb[%5d %5d]. Cut: %5d, Vol: %5d\n",
+             pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], 
+             1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd,
+             graph->mincut, graph->minvol));
+
+  for (pass=0; pass<npasses; pass++) {
+    ASSERT(ComputeCut(graph, where) == graph->mincut);
+
+    oldcut = graph->mincut;
+    oldvol = graph->minvol;
+
+    RandomPermute(graph->nbnd, perm, 1);
+    for (nmoves=iii=0; iii<graph->nbnd; iii++) {
+      ii = perm[iii];
+      if (ii >= graph->nbnd)
+        continue;
+      i = bndind[ii];
+      myrinfo = graph->vrinfo+i;
+
+      if (myrinfo->gv >= 0) { /* Total volume gain is too high */
+        from = where[i];
+        vwgt = graph->vwgt[i];
+
+        if (myrinfo->id > 0 && pwgts[from]-vwgt < minwgt[from]) 
+          continue;   /* This cannot be moved! */
+
+        xgain = (myrinfo->id == 0 && myrinfo->ed > 0 ? graph->vsize[i] : 0);
+
+        myedegrees = myrinfo->edegrees;
+        myndegrees = myrinfo->ndegrees;
+
+        for (k=0; k<myndegrees; k++) {
+          to = myedegrees[k].pid;
+          if (pwgts[to]+vwgt <= maxwgt[to]+ffactor*myedegrees[k].gv && xgain+myedegrees[k].gv >= 0)  
+            break;
+        }
+        if (k == myndegrees)
+          continue;  /* break out if you did not find a candidate */
+
+        for (j=k+1; j<myndegrees; j++) {
+          to = myedegrees[j].pid;
+          if (pwgts[to]+vwgt > maxwgt[to])
+            continue;
+          if (myedegrees[j].gv > myedegrees[k].gv ||
+              (myedegrees[j].gv == myedegrees[k].gv && myedegrees[j].ed > myedegrees[k].ed) ||
+              (myedegrees[j].gv == myedegrees[k].gv && myedegrees[j].ed == myedegrees[k].ed &&
+               itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid]))
+            k = j;
+        }
+
+        to = myedegrees[k].pid;
+
+        j = 0;
+        if (xgain+myedegrees[k].gv > 0 || myedegrees[k].ed-myrinfo->id > 0)
+          j = 1;
+        else if (myedegrees[k].ed-myrinfo->id == 0) {
+          if ((iii&5) == 0 || pwgts[from] >= maxwgt[from] || itpwgts[from]*(pwgts[to]+vwgt) < itpwgts[to]*pwgts[from])
+            j = 1;
+        }
+        if (j == 0)
+          continue;
+          
+        /*=====================================================================
+        * If we got here, we can now move the vertex from 'from' to 'to' 
+        *======================================================================*/
+        INC_DEC(pwgts[to], pwgts[from], vwgt);
+        graph->mincut -= myedegrees[k].ed-myrinfo->id;
+        graph->minvol -= (xgain+myedegrees[k].gv);
+        where[i] = to;
+
+        IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d from %3d to %3d. Gain: [%4d %4d]. Cut: %6d, Vol: %6d\n", 
+              i, from, to, xgain+myedegrees[k].gv, myedegrees[k].ed-myrinfo->id, graph->mincut, graph->minvol));
+
+        KWayVolUpdate(ctrl, graph, i, from, to, marker, phtable, updind);
+
+        nmoves++;
+
+        /* CheckVolKWayPartitionParams(ctrl, graph, nparts); */
+      }
+    }
+
+    IFSET(ctrl->dbglvl, DBG_REFINE,
+       printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, Vol: %6d\n",
+               pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)],
+               1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, graph->mincut, 
+               graph->minvol));
+
+    if (graph->minvol == oldvol && graph->mincut == oldcut)
+      break;
+  }
+
+  GKfree(&marker, &updind, &phtable, LTERM);
+
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+/*************************************************************************
+* This function performs k-way refinement
+**************************************************************************/
+void Random_KWayVolRefineMConn(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, 
+            float ubfactor, int npasses, int ffactor)
+{
+  int i, ii, iii, j, jj, k, kk, l, u, pass, nvtxs, nmoves, tvwgt, myndegrees, xgain; 
+  int from, me, to, oldcut, oldvol, vwgt, nadd, maxndoms;
+  idxtype *xadj, *adjncy, *adjwgt;
+  idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts, *updind, *marker, *phtable;
+  idxtype *pmat, *pmatptr, *ndoms;
+  VEDegreeType *myedegrees;
+  VRInfoType *myrinfo; 
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+
+  where = graph->where;
+  pwgts = graph->pwgts;
+  
+  /* Setup the weight intervals of the various subdomains */
+  minwgt =  idxwspacemalloc(ctrl, nparts);
+  maxwgt = idxwspacemalloc(ctrl, nparts);
+  itpwgts = idxwspacemalloc(ctrl, nparts);
+  tvwgt = idxsum(nparts, pwgts);
+  ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt));
+
+  updind = idxmalloc(nvtxs, "Random_KWayVolRefine: updind");
+  marker = idxsmalloc(nvtxs, 0, "Random_KWayVolRefine: marker");
+  phtable = idxsmalloc(nparts, -1, "Random_KWayVolRefine: phtable");
+
+  pmat = ctrl->wspace.pmat;
+  ndoms = idxwspacemalloc(ctrl, nparts);
+
+  ComputeVolSubDomainGraph(graph, nparts, pmat, ndoms);
+
+  for (i=0; i<nparts; i++) {
+    itpwgts[i] = tpwgts[i]*tvwgt;
+    maxwgt[i] = tpwgts[i]*tvwgt*ubfactor;
+    minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor);
+  }
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+
+  IFSET(ctrl->dbglvl, DBG_REFINE,
+     printf("VolPart: [%5d %5d]-[%5d %5d], Balance: %3.2f, Nv-Nb[%5d %5d]. Cut: %5d, Vol: %5d\n",
+             pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], 
+             1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd,
+             graph->mincut, graph->minvol));
+
+  for (pass=0; pass<npasses; pass++) {
+    ASSERT(ComputeCut(graph, where) == graph->mincut);
+
+    maxndoms = ndoms[idxamax(nparts, ndoms)];
+
+    oldcut = graph->mincut;
+    oldvol = graph->minvol;
+
+    RandomPermute(graph->nbnd, perm, 1);
+    for (nmoves=iii=0; iii<graph->nbnd; iii++) {
+      ii = perm[iii];
+      if (ii >= graph->nbnd)
+        continue;
+      i = bndind[ii];
+      myrinfo = graph->vrinfo+i;
+
+      if (myrinfo->gv >= 0) { /* Total volume gain is too high */
+        from = where[i];
+        vwgt = graph->vwgt[i];
+
+        if (myrinfo->id > 0 && pwgts[from]-vwgt < minwgt[from]) 
+          continue;   /* This cannot be moved! */
+
+        xgain = (myrinfo->id == 0 && myrinfo->ed > 0 ? graph->vsize[i] : 0);
+
+        myedegrees = myrinfo->edegrees;
+        myndegrees = myrinfo->ndegrees;
+
+        /* Determine the valid domains */
+        for (j=0; j<myndegrees; j++) {
+          to = myedegrees[j].pid;
+          phtable[to] = 1;
+          pmatptr = pmat + to*nparts;
+          for (nadd=0, k=0; k<myndegrees; k++) {
+            if (k == j)
+              continue;
+
+            l = myedegrees[k].pid;
+            if (pmatptr[l] == 0) {
+              if (ndoms[l] > maxndoms-1) {
+                phtable[to] = 0;
+                nadd = maxndoms;
+                break;
+              }
+              nadd++;
+            }
+          }
+          if (ndoms[to]+nadd > maxndoms)
+            phtable[to] = 0;
+          if (nadd == 0)
+            phtable[to] = 2;
+        }
+
+        for (k=0; k<myndegrees; k++) {
+          to = myedegrees[k].pid;
+          if (!phtable[to])
+            continue;
+          if (pwgts[to]+vwgt <= maxwgt[to]+ffactor*myedegrees[k].gv && xgain+myedegrees[k].gv >= 0)  
+            break;
+        }
+        if (k == myndegrees)
+          continue;  /* break out if you did not find a candidate */
+
+        for (j=k+1; j<myndegrees; j++) {
+          to = myedegrees[j].pid;
+          if (!phtable[to] || pwgts[to]+vwgt > maxwgt[to])
+            continue;
+          if (myedegrees[j].gv > myedegrees[k].gv ||
+              (myedegrees[j].gv == myedegrees[k].gv && myedegrees[j].ed > myedegrees[k].ed) ||
+              (myedegrees[j].gv == myedegrees[k].gv && myedegrees[j].ed == myedegrees[k].ed &&
+               itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid]))
+            k = j;
+        }
+
+        to = myedegrees[k].pid;
+
+        j = 0;
+        if (xgain+myedegrees[k].gv > 0 || myedegrees[k].ed-myrinfo->id > 0)
+          j = 1;
+        else if (myedegrees[k].ed-myrinfo->id == 0) {
+          if ((iii&5) == 0 || phtable[myedegrees[k].pid] == 2 || pwgts[from] >= maxwgt[from] || itpwgts[from]*(pwgts[to]+vwgt) < itpwgts[to]*pwgts[from])
+            j = 1;
+        }
+
+        if (j == 0)
+          continue;
+
+        for (j=0; j<myndegrees; j++) 
+          phtable[myedegrees[j].pid] = -1;
+
+          
+        /*=====================================================================
+        * If we got here, we can now move the vertex from 'from' to 'to' 
+        *======================================================================*/
+        INC_DEC(pwgts[to], pwgts[from], vwgt);
+        graph->mincut -= myedegrees[k].ed-myrinfo->id;
+        graph->minvol -= (xgain+myedegrees[k].gv);
+        where[i] = to;
+
+        IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d from %3d to %3d. Gain: [%4d %4d]. Cut: %6d, Vol: %6d\n", 
+              i, from, to, xgain+myedegrees[k].gv, myedegrees[k].ed-myrinfo->id, graph->mincut, graph->minvol));
+
+        /* Update pmat to reflect the move of 'i' */
+        pmat[from*nparts+to] += (myrinfo->id-myedegrees[k].ed);
+        pmat[to*nparts+from] += (myrinfo->id-myedegrees[k].ed);
+        if (pmat[from*nparts+to] == 0) {
+          ndoms[from]--;
+          if (ndoms[from]+1 == maxndoms)
+            maxndoms = ndoms[idxamax(nparts, ndoms)];
+        }
+        if (pmat[to*nparts+from] == 0) {
+          ndoms[to]--;
+          if (ndoms[to]+1 == maxndoms)
+            maxndoms = ndoms[idxamax(nparts, ndoms)];
+        }
+
+        for (j=xadj[i]; j<xadj[i+1]; j++) {
+          ii = adjncy[j];
+          me = where[ii];
+
+          /* Update pmat to reflect the move of 'i' for domains other than 'from' and 'to' */
+          if (me != from && me != to) {
+            pmat[me*nparts+from] -= adjwgt[j];
+            pmat[from*nparts+me] -= adjwgt[j];
+            if (pmat[me*nparts+from] == 0) {
+              ndoms[me]--;
+              if (ndoms[me]+1 == maxndoms)
+                maxndoms = ndoms[idxamax(nparts, ndoms)];
+            }
+            if (pmat[from*nparts+me] == 0) {
+              ndoms[from]--;
+              if (ndoms[from]+1 == maxndoms)
+                maxndoms = ndoms[idxamax(nparts, ndoms)];
+            }
+
+            if (pmat[me*nparts+to] == 0) {
+              ndoms[me]++;
+              if (ndoms[me] > maxndoms) {
+                printf("You just increased the maxndoms: %d %d\n", ndoms[me], maxndoms);
+                maxndoms = ndoms[me];
+              }
+            }
+            if (pmat[to*nparts+me] == 0) {
+              ndoms[to]++;
+              if (ndoms[to] > maxndoms) {
+                printf("You just increased the maxndoms: %d %d\n", ndoms[to], maxndoms);
+                maxndoms = ndoms[to];
+              }
+            }
+            pmat[me*nparts+to] += adjwgt[j];
+            pmat[to*nparts+me] += adjwgt[j];
+          }
+        }
+
+        KWayVolUpdate(ctrl, graph, i, from, to, marker, phtable, updind);
+
+        nmoves++;
+
+        /* CheckVolKWayPartitionParams(ctrl, graph, nparts); */
+      }
+    }
+
+    IFSET(ctrl->dbglvl, DBG_REFINE,
+       printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, Vol: %6d\n",
+               pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)],
+               1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, graph->mincut, 
+               graph->minvol));
+
+    if (graph->minvol == oldvol && graph->mincut == oldcut)
+      break;
+  }
+
+  GKfree(&marker, &updind, &phtable, LTERM);
+
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+
+
+/*************************************************************************
+* This function performs k-way refinement
+**************************************************************************/
+void Greedy_KWayVolBalance(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, 
+                           float ubfactor, int npasses)
+{
+  int i, ii, iii, j, jj, k, kk, l, u, pass, nvtxs, nmoves, tvwgt, myndegrees, xgain; 
+  int from, me, to, vwgt, gain;
+  idxtype *xadj, *adjncy, *adjwgt;
+  idxtype *where, *pwgts, *perm, *moved, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts, *updind, *marker, *phtable;
+  VEDegreeType *myedegrees;
+  VRInfoType *myrinfo; 
+  PQueueType queue;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+
+  where = graph->where;
+  pwgts = graph->pwgts;
+  
+  /* Setup the weight intervals of the various subdomains */
+  minwgt =  idxwspacemalloc(ctrl, nparts);
+  maxwgt = idxwspacemalloc(ctrl, nparts);
+  itpwgts = idxwspacemalloc(ctrl, nparts);
+  tvwgt = idxsum(nparts, pwgts);
+  ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt));
+
+  updind = idxmalloc(nvtxs, "Random_KWayVolRefine: updind");
+  marker = idxsmalloc(nvtxs, 0, "Random_KWayVolRefine: marker");
+  phtable = idxsmalloc(nparts, -1, "Random_KWayVolRefine: phtable");
+
+  for (i=0; i<nparts; i++) {
+    itpwgts[i] = tpwgts[i]*tvwgt;
+    maxwgt[i] = tpwgts[i]*tvwgt*ubfactor;
+    minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor);
+  }
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  moved = idxwspacemalloc(ctrl, nvtxs);
+
+  PQueueInit(ctrl, &queue, nvtxs, graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]);
+
+  IFSET(ctrl->dbglvl, DBG_REFINE,
+     printf("VolPart: [%5d %5d]-[%5d %5d], Balance: %3.2f, Nv-Nb[%5d %5d]. Cut: %5d, Vol: %5d [B]\n",
+             pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], 
+             1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd,
+             graph->mincut, graph->minvol));
+
+
+  for (pass=0; pass<npasses; pass++) {
+    ASSERT(ComputeCut(graph, where) == graph->mincut);
+    /* Check to see if things are out of balance, given the tolerance */
+    for (i=0; i<nparts; i++) {
+      if (pwgts[i] > maxwgt[i])
+        break;
+    }
+    if (i == nparts) /* Things are balanced. Return right away */
+      break;
+
+    PQueueReset(&queue);
+    idxset(nvtxs, -1, moved);
+
+    RandomPermute(graph->nbnd, perm, 1);
+    for (ii=0; ii<graph->nbnd; ii++) {
+      i = bndind[perm[ii]];
+      PQueueInsert(&queue, i, graph->vrinfo[i].gv);
+      moved[i] = 2;
+    }
+
+    for (nmoves=0;;) {
+      if ((i = PQueueGetMax(&queue)) == -1) 
+        break;
+      moved[i] = 1;
+
+      myrinfo = graph->vrinfo+i;
+      from = where[i];
+      vwgt = graph->vwgt[i];
+
+      if (pwgts[from]-vwgt < minwgt[from]) 
+        continue;   /* This cannot be moved! */
+
+      xgain = (myrinfo->id == 0 && myrinfo->ed > 0 ? graph->vsize[i] : 0);
+
+      myedegrees = myrinfo->edegrees;
+      myndegrees = myrinfo->ndegrees;
+
+      for (k=0; k<myndegrees; k++) {
+        to = myedegrees[k].pid;
+        if (pwgts[to]+vwgt <= maxwgt[to] || 
+            itpwgts[from]*(pwgts[to]+vwgt) <= itpwgts[to]*pwgts[from]) 
+          break;
+      }
+      if (k == myndegrees)
+        continue;  /* break out if you did not find a candidate */
+
+      for (j=k+1; j<myndegrees; j++) {
+        to = myedegrees[j].pid;
+        if (itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid]) 
+          k = j;
+      }
+
+      to = myedegrees[k].pid;
+
+      if (pwgts[from] < maxwgt[from] && pwgts[to] > minwgt[to] && 
+          (xgain+myedegrees[k].gv < 0 || 
+           (xgain+myedegrees[k].gv == 0 &&  myedegrees[k].ed-myrinfo->id < 0))
+         )
+        continue;
+  
+
+      /*=====================================================================
+      * If we got here, we can now move the vertex from 'from' to 'to' 
+      *======================================================================*/
+      INC_DEC(pwgts[to], pwgts[from], vwgt);
+      graph->mincut -= myedegrees[k].ed-myrinfo->id;
+      graph->minvol -= (xgain+myedegrees[k].gv);
+      where[i] = to;
+
+      IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d from %3d to %3d. Gain: [%4d %4d]. Cut: %6d, Vol: %6d\n", 
+            i, from, to, xgain+myedegrees[k].gv, myedegrees[k].ed-myrinfo->id, graph->mincut, graph->minvol));
+
+      KWayVolUpdate(ctrl, graph, i, from, to, marker, phtable, updind);
+
+      nmoves++;
+
+      /*CheckVolKWayPartitionParams(ctrl, graph, nparts); */
+    }
+
+    IFSET(ctrl->dbglvl, DBG_REFINE,
+       printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, Vol: %6d\n",
+               pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)],
+               1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, graph->mincut, 
+               graph->minvol));
+
+  }
+
+  GKfree(&marker, &updind, &phtable, LTERM);
+
+  PQueueFree(ctrl, &queue);
+
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+
+/*************************************************************************
+* This function performs k-way refinement
+**************************************************************************/
+void Greedy_KWayVolBalanceMConn(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, 
+                                float ubfactor, int npasses)
+{
+  int i, ii, iii, j, jj, k, kk, l, u, pass, nvtxs, nmoves, tvwgt, myndegrees, xgain; 
+  int from, me, to, vwgt, gain, maxndoms, nadd;
+  idxtype *xadj, *adjncy, *adjwgt;
+  idxtype *where, *pwgts, *perm, *moved, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts, *updind, *marker, *phtable;
+  idxtype *pmat, *pmatptr, *ndoms;
+  VEDegreeType *myedegrees;
+  VRInfoType *myrinfo; 
+  PQueueType queue;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+
+  where = graph->where;
+  pwgts = graph->pwgts;
+  
+  /* Setup the weight intervals of the various subdomains */
+  minwgt =  idxwspacemalloc(ctrl, nparts);
+  maxwgt = idxwspacemalloc(ctrl, nparts);
+  itpwgts = idxwspacemalloc(ctrl, nparts);
+  tvwgt = idxsum(nparts, pwgts);
+  ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt));
+
+  updind = idxmalloc(nvtxs, "Random_KWayVolRefine: updind");
+  marker = idxsmalloc(nvtxs, 0, "Random_KWayVolRefine: marker");
+  phtable = idxsmalloc(nparts, -1, "Random_KWayVolRefine: phtable");
+
+  pmat = ctrl->wspace.pmat;
+  ndoms = idxwspacemalloc(ctrl, nparts);
+
+  ComputeVolSubDomainGraph(graph, nparts, pmat, ndoms);
+
+  for (i=0; i<nparts; i++) {
+    itpwgts[i] = tpwgts[i]*tvwgt;
+    maxwgt[i] = tpwgts[i]*tvwgt*ubfactor;
+    minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor);
+  }
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  moved = idxwspacemalloc(ctrl, nvtxs);
+
+  PQueueInit(ctrl, &queue, nvtxs, graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]);
+
+  IFSET(ctrl->dbglvl, DBG_REFINE,
+     printf("VolPart: [%5d %5d]-[%5d %5d], Balance: %3.2f, Nv-Nb[%5d %5d]. Cut: %5d, Vol: %5d [B]\n",
+             pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], 
+             1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd,
+             graph->mincut, graph->minvol));
+
+
+  for (pass=0; pass<npasses; pass++) {
+    ASSERT(ComputeCut(graph, where) == graph->mincut);
+    /* Check to see if things are out of balance, given the tolerance */
+    for (i=0; i<nparts; i++) {
+      if (pwgts[i] > maxwgt[i])
+        break;
+    }
+    if (i == nparts) /* Things are balanced. Return right away */
+      break;
+
+    PQueueReset(&queue);
+    idxset(nvtxs, -1, moved);
+
+    RandomPermute(graph->nbnd, perm, 1);
+    for (ii=0; ii<graph->nbnd; ii++) {
+      i = bndind[perm[ii]];
+      PQueueInsert(&queue, i, graph->vrinfo[i].gv);
+      moved[i] = 2;
+    }
+
+    maxndoms = ndoms[idxamax(nparts, ndoms)];
+
+    for (nmoves=0;;) {
+      if ((i = PQueueGetMax(&queue)) == -1) 
+        break;
+      moved[i] = 1;
+
+      myrinfo = graph->vrinfo+i;
+      from = where[i];
+      vwgt = graph->vwgt[i];
+
+      if (pwgts[from]-vwgt < minwgt[from]) 
+        continue;   /* This cannot be moved! */
+
+      xgain = (myrinfo->id == 0 && myrinfo->ed > 0 ? graph->vsize[i] : 0);
+
+      myedegrees = myrinfo->edegrees;
+      myndegrees = myrinfo->ndegrees;
+
+      /* Determine the valid domains */
+      for (j=0; j<myndegrees; j++) {
+        to = myedegrees[j].pid;
+        phtable[to] = 1;
+        pmatptr = pmat + to*nparts;
+        for (nadd=0, k=0; k<myndegrees; k++) {
+          if (k == j)
+            continue;
+
+          l = myedegrees[k].pid;
+          if (pmatptr[l] == 0) {
+            if (ndoms[l] > maxndoms-1) {
+              phtable[to] = 0;
+              nadd = maxndoms;
+              break;
+            }
+            nadd++;
+          }
+        }
+        if (ndoms[to]+nadd > maxndoms)
+          phtable[to] = 0;
+      }
+
+      for (k=0; k<myndegrees; k++) {
+        to = myedegrees[k].pid;
+        if (!phtable[to])
+          continue;
+        if (pwgts[to]+vwgt <= maxwgt[to] || 
+            itpwgts[from]*(pwgts[to]+vwgt) <= itpwgts[to]*pwgts[from]) 
+          break;
+      }
+      if (k == myndegrees)
+        continue;  /* break out if you did not find a candidate */
+
+      for (j=k+1; j<myndegrees; j++) {
+        to = myedegrees[j].pid;
+        if (!phtable[to])
+          continue;
+        if (itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid]) 
+          k = j;
+      }
+
+      to = myedegrees[k].pid;
+
+      for (j=0; j<myndegrees; j++) 
+        phtable[myedegrees[j].pid] = -1;
+
+      if (pwgts[from] < maxwgt[from] && pwgts[to] > minwgt[to] && 
+          (xgain+myedegrees[k].gv < 0 || 
+           (xgain+myedegrees[k].gv == 0 &&  myedegrees[k].ed-myrinfo->id < 0))
+         )
+        continue;
+  
+
+      /*=====================================================================
+      * If we got here, we can now move the vertex from 'from' to 'to' 
+      *======================================================================*/
+      INC_DEC(pwgts[to], pwgts[from], vwgt);
+      graph->mincut -= myedegrees[k].ed-myrinfo->id;
+      graph->minvol -= (xgain+myedegrees[k].gv);
+      where[i] = to;
+
+      IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d from %3d to %3d. Gain: [%4d %4d]. Cut: %6d, Vol: %6d\n", 
+            i, from, to, xgain+myedegrees[k].gv, myedegrees[k].ed-myrinfo->id, graph->mincut, graph->minvol));
+
+      /* Update pmat to reflect the move of 'i' */
+      pmat[from*nparts+to] += (myrinfo->id-myedegrees[k].ed);
+      pmat[to*nparts+from] += (myrinfo->id-myedegrees[k].ed);
+      if (pmat[from*nparts+to] == 0) {
+        ndoms[from]--;
+        if (ndoms[from]+1 == maxndoms)
+          maxndoms = ndoms[idxamax(nparts, ndoms)];
+      }
+      if (pmat[to*nparts+from] == 0) {
+        ndoms[to]--;
+        if (ndoms[to]+1 == maxndoms)
+          maxndoms = ndoms[idxamax(nparts, ndoms)];
+      }
+
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        ii = adjncy[j];
+        me = where[ii];
+
+        /* Update pmat to reflect the move of 'i' for domains other than 'from' and 'to' */
+        if (me != from && me != to) {
+          pmat[me*nparts+from] -= adjwgt[j];
+          pmat[from*nparts+me] -= adjwgt[j];
+          if (pmat[me*nparts+from] == 0) {
+            ndoms[me]--;
+            if (ndoms[me]+1 == maxndoms)
+              maxndoms = ndoms[idxamax(nparts, ndoms)];
+          }
+          if (pmat[from*nparts+me] == 0) {
+            ndoms[from]--;
+            if (ndoms[from]+1 == maxndoms)
+              maxndoms = ndoms[idxamax(nparts, ndoms)];
+          }
+
+          if (pmat[me*nparts+to] == 0) {
+            ndoms[me]++;
+            if (ndoms[me] > maxndoms) {
+              printf("You just increased the maxndoms: %d %d\n", ndoms[me], maxndoms);
+              maxndoms = ndoms[me];
+            }
+          }
+          if (pmat[to*nparts+me] == 0) {
+            ndoms[to]++;
+            if (ndoms[to] > maxndoms) {
+              printf("You just increased the maxndoms: %d %d\n", ndoms[to], maxndoms);
+              maxndoms = ndoms[to];
+            }
+          }
+          pmat[me*nparts+to] += adjwgt[j];
+          pmat[to*nparts+me] += adjwgt[j];
+        }
+      }
+
+      KWayVolUpdate(ctrl, graph, i, from, to, marker, phtable, updind);
+
+      nmoves++;
+
+      /*CheckVolKWayPartitionParams(ctrl, graph, nparts); */
+    }
+
+    IFSET(ctrl->dbglvl, DBG_REFINE,
+       printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, Vol: %6d\n",
+               pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)],
+               1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, graph->mincut, 
+               graph->minvol));
+
+  }
+
+  GKfree(&marker, &updind, &phtable, LTERM);
+
+  PQueueFree(ctrl, &queue);
+
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+
+
+/*************************************************************************
+* This function updates the edge and volume gains as a result of moving
+* v from 'from' to 'to'.
+* The working arrays marker and phtable are assumed to be initialized to
+* -1, and they left to -1 upon return
+**************************************************************************/
+void KWayVolUpdate(CtrlType *ctrl, GraphType *graph, int v, int from, int to,
+                   idxtype *marker, idxtype *phtable, idxtype *updind)
+{
+  int ii, iii, j, jj, k, kk, l, u, nupd, other, me, myidx; 
+  idxtype *xadj, *vsize, *adjncy, *adjwgt, *where;
+  VEDegreeType *myedegrees, *oedegrees;
+  VRInfoType *myrinfo, *orinfo;
+
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+  vsize = graph->vsize;
+  where = graph->where;
+
+  myrinfo = graph->vrinfo+v;
+  myedegrees = myrinfo->edegrees;
+
+
+  /*======================================================================
+   * Remove the contributions on the gain made by 'v'. 
+   *=====================================================================*/
+  for (k=0; k<myrinfo->ndegrees; k++)
+    phtable[myedegrees[k].pid] = k;
+  phtable[from] = k;
+
+  myidx = phtable[to];  /* Keep track of the index in myedegrees of the 'to' domain */
+
+  for (j=xadj[v]; j<xadj[v+1]; j++) {
+    ii = adjncy[j];
+    other = where[ii];
+    orinfo = graph->vrinfo+ii;
+    oedegrees = orinfo->edegrees;
+
+    if (other == from) {
+      for (k=0; k<orinfo->ndegrees; k++) {
+        if (phtable[oedegrees[k].pid] == -1) 
+          oedegrees[k].gv += vsize[v];
+      }
+    }
+    else {
+      ASSERT(phtable[other] != -1);
+
+      if (myedegrees[phtable[other]].ned > 1) {
+        for (k=0; k<orinfo->ndegrees; k++) {
+          if (phtable[oedegrees[k].pid] == -1) 
+            oedegrees[k].gv += vsize[v];
+        }
+      }
+      else { /* There is only one connection */
+        for (k=0; k<orinfo->ndegrees; k++) {
+          if (phtable[oedegrees[k].pid] != -1) 
+            oedegrees[k].gv -= vsize[v];
+        }
+      }
+    }
+  }
+
+  for (k=0; k<myrinfo->ndegrees; k++)
+    phtable[myedegrees[k].pid] = -1;
+  phtable[from] = -1;
+
+
+  /*======================================================================
+   * Update the id/ed of vertex 'v'
+   *=====================================================================*/
+  myrinfo->ed += myrinfo->id-myedegrees[myidx].ed;
+  SWAP(myrinfo->id, myedegrees[myidx].ed, j);
+  SWAP(myrinfo->nid, myedegrees[myidx].ned, j);
+  if (myedegrees[myidx].ed == 0) 
+    myedegrees[myidx] = myedegrees[--myrinfo->ndegrees];
+  else
+    myedegrees[myidx].pid = from;
+
+  /*======================================================================
+   * Update the degrees of adjacent vertices and their volume gains
+   *=====================================================================*/
+  marker[v] = 1;
+  updind[0] = v;
+  nupd = 1;
+  for (j=xadj[v]; j<xadj[v+1]; j++) {
+    ii = adjncy[j];
+    me = where[ii];
+
+    if (!marker[ii]) {  /* The marking is done for boundary and max gv calculations */
+      marker[ii] = 2;
+      updind[nupd++] = ii;
+    }
+
+    myrinfo = graph->vrinfo+ii;
+    if (myrinfo->edegrees == NULL) {
+      myrinfo->edegrees = ctrl->wspace.vedegrees+ctrl->wspace.cdegree;
+      ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii];
+    }
+    myedegrees = myrinfo->edegrees;
+
+    if (me == from) {
+      INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]);
+      myrinfo->nid--;
+    } 
+    else if (me == to) {
+      INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]);
+      myrinfo->nid++;
+    }
+
+    /* Remove the edgeweight from the 'pid == from' entry of the vertex */
+    if (me != from) {
+      for (k=0; k<myrinfo->ndegrees; k++) {
+        if (myedegrees[k].pid == from) {
+          if (myedegrees[k].ned == 1) {
+            myedegrees[k] = myedegrees[--myrinfo->ndegrees];
+            marker[ii] = 1;  /* You do a complete .gv calculation */
+
+            /* All vertices adjacent to 'ii' need to be updated */
+            for (jj=xadj[ii]; jj<xadj[ii+1]; jj++) {
+              u = adjncy[jj];
+              other = where[u];
+              orinfo = graph->vrinfo+u;
+              oedegrees = orinfo->edegrees;
+
+              for (kk=0; kk<orinfo->ndegrees; kk++) {
+                if (oedegrees[kk].pid == from) {
+                  oedegrees[kk].gv -= vsize[ii];
+                  break;
+                }
+              }
+            }
+          }
+          else {
+            myedegrees[k].ed -= adjwgt[j];
+            myedegrees[k].ned--;
+
+            /* Update the gv due to single 'ii' connection to 'from' */
+            if (myedegrees[k].ned == 1) {
+              /* find the vertex 'u' that 'ii' was connected into 'from' */
+              for (jj=xadj[ii]; jj<xadj[ii+1]; jj++) {
+                u = adjncy[jj];
+                other = where[u];
+                orinfo = graph->vrinfo+u;
+                oedegrees = orinfo->edegrees;
+
+                if (other == from) {
+                  for (kk=0; kk<orinfo->ndegrees; kk++) 
+                    oedegrees[kk].gv += vsize[ii];
+                  break;  
+                }
+              }
+            }
+          }
+
+          break; 
+        }
+      }
+    }
+
+    /* Add the edgeweight to the 'pid == to' entry of the vertex */
+    if (me != to) {
+      for (k=0; k<myrinfo->ndegrees; k++) {
+        if (myedegrees[k].pid == to) {
+          myedegrees[k].ed += adjwgt[j];
+          myedegrees[k].ned++;
+
+          /* Update the gv due to non-single 'ii' connection to 'to' */
+          if (myedegrees[k].ned == 2) {
+            /* find the vertex 'u' that 'ii' was connected into 'to' */
+            for (jj=xadj[ii]; jj<xadj[ii+1]; jj++) {
+              u = adjncy[jj];
+              other = where[u];
+              orinfo = graph->vrinfo+u;
+              oedegrees = orinfo->edegrees;
+
+              if (u != v && other == to) {
+                for (kk=0; kk<orinfo->ndegrees; kk++) 
+                  oedegrees[kk].gv -= vsize[ii];
+                break;  
+              }
+            }
+          }
+          break;
+        }
+      }
+
+      if (k == myrinfo->ndegrees) {
+        myedegrees[myrinfo->ndegrees].pid = to;
+        myedegrees[myrinfo->ndegrees].ed = adjwgt[j];
+        myedegrees[myrinfo->ndegrees++].ned = 1;
+        marker[ii] = 1;  /* You do a complete .gv calculation */
+
+        /* All vertices adjacent to 'ii' need to be updated */
+        for (jj=xadj[ii]; jj<xadj[ii+1]; jj++) {
+          u = adjncy[jj];
+          other = where[u];
+          orinfo = graph->vrinfo+u;
+          oedegrees = orinfo->edegrees;
+
+          for (kk=0; kk<orinfo->ndegrees; kk++) {
+            if (oedegrees[kk].pid == to) {
+              oedegrees[kk].gv += vsize[ii];
+              if (!marker[u]) { /* Need to update boundary etc */
+                marker[u] = 2;
+                updind[nupd++] = u;
+              }
+              break;
+            }
+          }
+        }
+      }
+    }
+
+    ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]);
+  }
+
+  /*======================================================================
+   * Add the contributions on the volume gain due to 'v'
+   *=====================================================================*/
+  myrinfo = graph->vrinfo+v;
+  myedegrees = myrinfo->edegrees;
+  for (k=0; k<myrinfo->ndegrees; k++)
+    phtable[myedegrees[k].pid] = k;
+  phtable[to] = k;
+
+  for (j=xadj[v]; j<xadj[v+1]; j++) {
+    ii = adjncy[j];
+    other = where[ii];
+    orinfo = graph->vrinfo+ii;
+    oedegrees = orinfo->edegrees;
+
+    if (other == to) {
+      for (k=0; k<orinfo->ndegrees; k++) {
+        if (phtable[oedegrees[k].pid] == -1) 
+          oedegrees[k].gv -= vsize[v];
+      }
+    }
+    else {
+      ASSERT(phtable[other] != -1);
+
+      if (myedegrees[phtable[other]].ned > 1) {
+        for (k=0; k<orinfo->ndegrees; k++) {
+          if (phtable[oedegrees[k].pid] == -1) 
+            oedegrees[k].gv -= vsize[v];
+        }
+      }
+      else { /* There is only one connection */
+        for (k=0; k<orinfo->ndegrees; k++) {
+          if (phtable[oedegrees[k].pid] != -1) 
+            oedegrees[k].gv += vsize[v];
+        }
+      }
+    }
+  }
+  for (k=0; k<myrinfo->ndegrees; k++)
+    phtable[myedegrees[k].pid] = -1;
+  phtable[to] = -1;
+
+
+  /*======================================================================
+   * Recompute the volume information of the 'hard' nodes, and update the
+   * max volume gain for all the update vertices
+   *=====================================================================*/
+  ComputeKWayVolume(graph, nupd, updind, marker, phtable);
+
+
+  /*======================================================================
+   * Maintain a consistent boundary
+   *=====================================================================*/
+  for (j=0; j<nupd; j++) {
+    k = updind[j];
+    marker[k] = 0;
+    myrinfo = graph->vrinfo+k;
+
+    if ((myrinfo->gv >= 0 || myrinfo->ed-myrinfo->id >= 0) && graph->bndptr[k] == -1)
+      BNDInsert(graph->nbnd, graph->bndind, graph->bndptr, k);
+
+    if (myrinfo->gv < 0 && myrinfo->ed-myrinfo->id < 0 && graph->bndptr[k] != -1)
+      BNDDelete(graph->nbnd, graph->bndind, graph->bndptr, k);
+  }
+
+}
+
+
+
+
+/*************************************************************************
+* This function computes the initial id/ed 
+**************************************************************************/
+void ComputeKWayVolume(GraphType *graph, int nupd, idxtype *updind, idxtype *marker, idxtype *phtable)
+{
+  int ii, iii, i, j, k, kk, l, nvtxs, me, other, pid;
+  idxtype *xadj, *vsize, *adjncy, *adjwgt, *where;
+  VRInfoType *rinfo, *myrinfo, *orinfo;
+  VEDegreeType *myedegrees, *oedegrees;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  vsize = graph->vsize;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+  where = graph->where;
+  rinfo = graph->vrinfo;
+
+
+  /*------------------------------------------------------------
+  / Compute now the iv/ev degrees
+  /------------------------------------------------------------*/
+  for (iii=0; iii<nupd; iii++) {
+    i = updind[iii];
+    me = where[i];
+
+    myrinfo = rinfo+i;
+    myedegrees = myrinfo->edegrees;
+
+    if (marker[i] == 1) {  /* Only complete gain updates go through */
+      for (k=0; k<myrinfo->ndegrees; k++) 
+        myedegrees[k].gv = 0;
+
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        ii = adjncy[j];
+        other = where[ii];
+        orinfo = rinfo+ii;
+        oedegrees = orinfo->edegrees;
+
+        for (kk=0; kk<orinfo->ndegrees; kk++) 
+          phtable[oedegrees[kk].pid] = kk;
+        phtable[other] = 1;
+
+        if (me == other) {
+          /* Find which domains 'i' is connected and 'ii' is not and update their gain */
+          for (k=0; k<myrinfo->ndegrees; k++) {
+            if (phtable[myedegrees[k].pid] == -1)
+              myedegrees[k].gv -= vsize[ii];
+          }
+        }
+        else {
+          ASSERT(phtable[me] != -1);
+
+          /* I'm the only connection of 'ii' in 'me' */
+          if (oedegrees[phtable[me]].ned == 1) { 
+            /* Increase the gains for all the common domains between 'i' and 'ii' */
+            for (k=0; k<myrinfo->ndegrees; k++) {
+              if (phtable[myedegrees[k].pid] != -1) 
+                myedegrees[k].gv += vsize[ii];
+            }
+          }
+          else {
+            /* Find which domains 'i' is connected and 'ii' is not and update their gain */
+            for (k=0; k<myrinfo->ndegrees; k++) {
+              if (phtable[myedegrees[k].pid] == -1) 
+                myedegrees[k].gv -= vsize[ii];
+            }
+          }
+        }
+
+        for (kk=0; kk<orinfo->ndegrees; kk++) 
+          phtable[oedegrees[kk].pid] = -1;
+        phtable[other] = -1;
+  
+      }
+    }
+
+    myrinfo->gv = -MAXIDX;
+    for (k=0; k<myrinfo->ndegrees; k++) {
+      if (myedegrees[k].gv > myrinfo->gv)
+        myrinfo->gv = myedegrees[k].gv;
+    }
+    if (myrinfo->ed > 0 && myrinfo->id == 0)
+      myrinfo->gv += vsize[i];
+
+  }
+
+}
+
+
+
+/*************************************************************************
+* This function computes the total volume
+**************************************************************************/
+int ComputeVolume(GraphType *graph, idxtype *where)
+{
+  int i, j, k, me, nvtxs, nparts, totalv;
+  idxtype *xadj, *adjncy, *vsize, *marker;
+
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  vsize = (graph->vsize == NULL ? graph->vwgt : graph->vsize);
+
+  nparts = where[idxamax(nvtxs, where)]+1;
+  marker = idxsmalloc(nparts, -1, "ComputeVolume: marker");
+
+  totalv = 0;
+
+  for (i=0; i<nvtxs; i++) {
+    marker[where[i]] = i;
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      k = where[adjncy[j]];
+      if (marker[k] != i) {
+        marker[k] = i;
+        totalv += vsize[i];
+      }
+    }
+  }
+
+  free(marker);
+
+  return totalv;
+}
+
+
+
+
+
+/*************************************************************************
+* This function computes the initial id/ed 
+**************************************************************************/
+void CheckVolKWayPartitionParams(CtrlType *ctrl, GraphType *graph, int nparts)
+{
+  int i, ii, j, k, kk, l, nvtxs, nbnd, mincut, minvol, me, other, pid;
+  idxtype *xadj, *vsize, *adjncy, *adjwgt, *pwgts, *where, *bndind, *bndptr;
+  VRInfoType *rinfo, *myrinfo, *orinfo, tmprinfo;
+  VEDegreeType *myedegrees, *oedegrees, *tmpdegrees;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  vsize = graph->vsize;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+  where = graph->where;
+  rinfo = graph->vrinfo;
+
+  tmpdegrees = (VEDegreeType *)GKmalloc(nparts*sizeof(VEDegreeType), "CheckVolKWayPartitionParams: tmpdegrees");
+
+  /*------------------------------------------------------------
+  / Compute now the iv/ev degrees
+  /------------------------------------------------------------*/
+  for (i=0; i<nvtxs; i++) {
+    me = where[i];
+
+    myrinfo = rinfo+i;
+    myedegrees = myrinfo->edegrees;
+
+    for (k=0; k<myrinfo->ndegrees; k++)
+      tmpdegrees[k] = myedegrees[k];
+
+    tmprinfo.ndegrees = myrinfo->ndegrees;
+    tmprinfo.id = myrinfo->id;
+    tmprinfo.ed = myrinfo->ed;
+
+    myrinfo = &tmprinfo;
+    myedegrees = tmpdegrees;
+
+
+    for (k=0; k<myrinfo->ndegrees; k++)
+      myedegrees[k].gv = 0;
+
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      ii = adjncy[j];
+      other = where[ii];
+      orinfo = rinfo+ii;
+      oedegrees = orinfo->edegrees;
+
+      if (me == other) {
+        /* Find which domains 'i' is connected and 'ii' is not and update their gain */
+        for (k=0; k<myrinfo->ndegrees; k++) {
+          pid = myedegrees[k].pid;
+          for (kk=0; kk<orinfo->ndegrees; kk++) {
+            if (oedegrees[kk].pid == pid)
+              break;
+          }
+          if (kk == orinfo->ndegrees) 
+            myedegrees[k].gv -= vsize[ii];
+        }
+      }
+      else {
+        /* Find the orinfo[me].ed and see if I'm the only connection */
+        for (k=0; k<orinfo->ndegrees; k++) {
+          if (oedegrees[k].pid == me)
+            break;
+        }
+
+        if (oedegrees[k].ned == 1) { /* I'm the only connection of 'ii' in 'me' */
+          for (k=0; k<myrinfo->ndegrees; k++) {
+            if (myedegrees[k].pid == other) {
+              myedegrees[k].gv += vsize[ii];
+              break;
+            }
+          }
+
+          /* Increase the gains for all the common domains between 'i' and 'ii' */
+          for (k=0; k<myrinfo->ndegrees; k++) {
+            if ((pid = myedegrees[k].pid) == other)
+              continue;
+            for (kk=0; kk<orinfo->ndegrees; kk++) {
+              if (oedegrees[kk].pid == pid) {
+                myedegrees[k].gv += vsize[ii];
+                break;
+              }
+            }
+          }
+
+        }
+        else {
+          /* Find which domains 'i' is connected and 'ii' is not and update their gain */
+          for (k=0; k<myrinfo->ndegrees; k++) {
+            if ((pid = myedegrees[k].pid) == other)
+              continue;
+            for (kk=0; kk<orinfo->ndegrees; kk++) {
+              if (oedegrees[kk].pid == pid)
+                break;
+            }
+            if (kk == orinfo->ndegrees) 
+              myedegrees[k].gv -= vsize[ii];
+          }
+        }
+      }
+    }
+
+    myrinfo = rinfo+i;
+    myedegrees = myrinfo->edegrees;
+
+    for (k=0; k<myrinfo->ndegrees; k++) {
+      pid = myedegrees[k].pid;
+      for (kk=0; kk<tmprinfo.ndegrees; kk++) {
+        if (tmpdegrees[kk].pid == pid) {
+          if (tmpdegrees[kk].gv != myedegrees[k].gv)
+            printf("[%d %d %d %d]\n", i, pid, myedegrees[k].gv, tmpdegrees[kk].gv);
+          break;
+        }
+      }
+    }
+
+  }
+
+  free(tmpdegrees);
+
+}
+
+
+/*************************************************************************
+* This function computes the subdomain graph
+**************************************************************************/
+void ComputeVolSubDomainGraph(GraphType *graph, int nparts, idxtype *pmat, idxtype *ndoms)
+{
+  int i, j, k, me, nvtxs, ndegrees;
+  idxtype *xadj, *adjncy, *adjwgt, *where;
+  VRInfoType *rinfo;
+  VEDegreeType *edegrees;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+  where = graph->where;
+  rinfo = graph->vrinfo;
+
+  idxset(nparts*nparts, 0, pmat);
+
+  for (i=0; i<nvtxs; i++) {
+    if (rinfo[i].ed > 0) {
+      me = where[i];
+      ndegrees = rinfo[i].ndegrees;
+      edegrees = rinfo[i].edegrees;
+
+      k = me*nparts;
+      for (j=0; j<ndegrees; j++) 
+        pmat[k+edegrees[j].pid] += edegrees[j].ed;
+    }
+  }
+
+  for (i=0; i<nparts; i++) {
+    ndoms[i] = 0;
+    for (j=0; j<nparts; j++) {
+      if (pmat[i*nparts+j] > 0)
+        ndoms[i]++;
+    }
+  }
+}
+
+
+
+/*************************************************************************
+* This function computes the subdomain graph
+**************************************************************************/
+void EliminateVolSubDomainEdges(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts)
+{
+  int i, ii, j, k, me, other, nvtxs, total, max, avg, totalout, nind, ncand, ncand2, target, target2, nadd;
+  int min, move, cpwgt, tvwgt;
+  idxtype *xadj, *adjncy, *vwgt, *adjwgt, *pwgts, *where, *maxpwgt, *pmat, *ndoms, *mypmat, *otherpmat, *ind;
+  KeyValueType *cand, *cand2;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  vwgt = graph->vwgt;
+  adjwgt = graph->adjwgt;
+
+  where = graph->where;
+  pwgts = idxset(nparts, 0, graph->pwgts);
+
+  maxpwgt = idxwspacemalloc(ctrl, nparts);
+  ndoms = idxwspacemalloc(ctrl, nparts);
+  otherpmat = idxwspacemalloc(ctrl, nparts);
+  ind = idxwspacemalloc(ctrl, nvtxs);
+  pmat = idxset(nparts*nparts, 0, ctrl->wspace.pmat);
+
+  cand = (KeyValueType *)GKmalloc(nparts*sizeof(KeyValueType), "EliminateSubDomainEdges: cand");
+  cand2 = (KeyValueType *)GKmalloc(nparts*sizeof(KeyValueType), "EliminateSubDomainEdges: cand");
+
+  /* Compute the pmat matrix */
+  for (i=0; i<nvtxs; i++) {
+    me = where[i];
+    pwgts[me] += vwgt[i];
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      k = adjncy[j];
+      if (where[k] != me) 
+        pmat[me*nparts+where[k]] += adjwgt[j];
+    }
+  }
+
+  /* Compute the maximum allowed weight for each domain */
+  tvwgt = idxsum(nparts, pwgts);
+  for (i=0; i<nparts; i++)
+    maxpwgt[i] = 1.25*tpwgts[i]*tvwgt;
+
+  /* Determine the domain connectivity */
+  for (i=0; i<nparts; i++) {
+    for (k=0, j=0; j<nparts; j++) {
+      if (pmat[i*nparts+j] > 0)
+        k++;
+    }
+    ndoms[i] = k;
+  }
+
+  /* Get into the loop eliminating subdomain connections */
+  for (;;) {
+    total = idxsum(nparts, ndoms);
+    avg = total/nparts;
+    max = ndoms[idxamax(nparts, ndoms)];
+
+    /* printf("Adjacent Subdomain Stats: Total: %3d, Max: %3d, Avg: %3d\n", total, max, avg); */
+
+    if (max < 1.5*avg)
+      break;
+
+    me = idxamax(nparts, ndoms);
+    mypmat = pmat + me*nparts;
+    totalout = idxsum(nparts, mypmat);
+
+    /*printf("Me: %d, TotalOut: %d,\n", me, totalout);*/
+
+    /* Sort the connections according to their cut */
+    for (ncand2=0, i=0; i<nparts; i++) {
+      if (mypmat[i] > 0) {
+        cand2[ncand2].key = mypmat[i];
+        cand2[ncand2++].val = i;
+      }
+    }
+    ikeysort(ncand2, cand2);
+
+    move = 0;
+    for (min=0; min<ncand2; min++) {
+      if (cand2[min].key > totalout/(2*ndoms[me])) 
+        break;
+
+      other = cand2[min].val;
+
+      /*printf("\tMinOut: %d to %d\n", mypmat[other], other);*/
+
+      idxset(nparts, 0, otherpmat);
+
+      /* Go and find the vertices in 'other' that are connected in 'me' */
+      for (nind=0, i=0; i<nvtxs; i++) {
+        if (where[i] == other) {
+          for (j=xadj[i]; j<xadj[i+1]; j++) {
+            if (where[adjncy[j]] == me) {
+              ind[nind++] = i;
+              break;
+            }
+          }
+        }
+      }
+
+      /* Go and construct the otherpmat to see where these nind vertices are connected to */
+      for (cpwgt=0, ii=0; ii<nind; ii++) {
+        i = ind[ii];
+        cpwgt += vwgt[i];
+
+        for (j=xadj[i]; j<xadj[i+1]; j++) {
+          k = adjncy[j];
+          if (where[k] != other) 
+            otherpmat[where[k]] += adjwgt[j];
+        }
+      }
+
+      for (ncand=0, i=0; i<nparts; i++) {
+        if (otherpmat[i] > 0) {
+          cand[ncand].key = -otherpmat[i];
+          cand[ncand++].val = i;
+        }
+      }
+      ikeysort(ncand, cand);
+
+      /* 
+       * Go through and the select the first domain that is common with 'me', and
+       * does not increase the ndoms[target] higher than my ndoms, subject to the
+       * maxpwgt constraint. Traversal is done from the mostly connected to the least.
+       */
+      target = target2 = -1;
+      for (i=0; i<ncand; i++) {
+        k = cand[i].val;
+
+        if (mypmat[k] > 0) {
+          if (pwgts[k] + cpwgt > maxpwgt[k])  /* Check if balance will go off */
+            continue;
+
+          for (j=0; j<nparts; j++) {
+            if (otherpmat[j] > 0 && ndoms[j] >= ndoms[me]-1 && pmat[nparts*j+k] == 0)
+              break;
+          }
+          if (j == nparts) { /* No bad second level effects */
+            for (nadd=0, j=0; j<nparts; j++) {
+              if (otherpmat[j] > 0 && pmat[nparts*k+j] == 0)
+                nadd++;
+            }
+
+            /*printf("\t\tto=%d, nadd=%d, %d\n", k, nadd, ndoms[k]);*/
+            if (target2 == -1 && ndoms[k]+nadd < ndoms[me]) {
+              target2 = k;
+            }
+            if (nadd == 0) {
+              target = k;
+              break;
+            }
+          }
+        }
+      }
+      if (target == -1 && target2 != -1)
+        target = target2;
+
+      if (target == -1) {
+        /* printf("\t\tCould not make the move\n");*/
+        continue;
+      }
+
+      /*printf("\t\tMoving to %d\n", target);*/
+
+      /* Update the partition weights */
+      INC_DEC(pwgts[target], pwgts[other], cpwgt);
+
+      /* Set all nind vertices to belong to 'target' */
+      for (ii=0; ii<nind; ii++) {
+        i = ind[ii];
+        where[i] = target;
+
+        /* First remove any contribution that this vertex may have made */
+        for (j=xadj[i]; j<xadj[i+1]; j++) {
+          k = adjncy[j];
+          if (where[k] != other) {
+            if (pmat[nparts*other + where[k]] == 0)
+              printf("Something wrong\n");
+            pmat[nparts*other + where[k]] -= adjwgt[j];
+            if (pmat[nparts*other + where[k]] == 0)
+              ndoms[other]--;
+
+            if (pmat[nparts*where[k] + other] == 0)
+              printf("Something wrong\n");
+            pmat[nparts*where[k] + other] -= adjwgt[j];
+            if (pmat[nparts*where[k] + other] == 0)
+              ndoms[where[k]]--;
+          }
+        }
+
+        /* Next add the new contributions as a result of the move */
+        for (j=xadj[i]; j<xadj[i+1]; j++) {
+          k = adjncy[j];
+          if (where[k] != target) {
+            if (pmat[nparts*target + where[k]] == 0)
+              ndoms[target]++;
+            pmat[nparts*target + where[k]] += adjwgt[j];
+  
+            if (pmat[nparts*where[k] + target] == 0)
+              ndoms[where[k]]++;
+            pmat[nparts*where[k] + target] += adjwgt[j];
+          }
+        }
+      }
+
+      move = 1;
+      break;
+    }
+
+    if (move == 0)
+      break;
+  }
+
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nvtxs);
+
+  GKfree(&cand, &cand2, LTERM);
+}
+
+
+
+/*************************************************************************
+* This function finds all the connected components induced by the 
+* partitioning vector in wgraph->where and tries to push them around to 
+* remove some of them
+**************************************************************************/
+void EliminateVolComponents(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor)
+{
+  int i, ii, j, jj, k, me, nvtxs, tvwgt, first, last, nleft, ncmps, cwgt, ncand, other, target, deltawgt;
+  idxtype *xadj, *adjncy, *vwgt, *adjwgt, *where, *pwgts, *maxpwgt;
+  idxtype *cpvec, *touched, *perm, *todo, *cind, *cptr, *npcmps;
+  KeyValueType *cand;
+  int recompute=0;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  vwgt = graph->vwgt;
+  adjwgt = graph->adjwgt;
+
+  where = graph->where;
+  pwgts = idxset(nparts, 0, graph->pwgts);
+
+  touched = idxset(nvtxs, 0, idxwspacemalloc(ctrl, nvtxs));
+  cptr = idxwspacemalloc(ctrl, nvtxs);
+  cind = idxwspacemalloc(ctrl, nvtxs);
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  todo = idxwspacemalloc(ctrl, nvtxs);
+  maxpwgt = idxwspacemalloc(ctrl, nparts);
+  cpvec = idxwspacemalloc(ctrl, nparts);
+  npcmps = idxset(nparts, 0, idxwspacemalloc(ctrl, nparts));
+
+  for (i=0; i<nvtxs; i++) 
+    perm[i] = todo[i] = i;
+
+  /* Find the connected componends induced by the partition */
+  ncmps = -1;
+  first = last = 0;
+  nleft = nvtxs;
+  while (nleft > 0) {
+    if (first == last) { /* Find another starting vertex */
+      cptr[++ncmps] = first;
+      ASSERT(touched[todo[0]] == 0);
+      i = todo[0];
+      cind[last++] = i;
+      touched[i] = 1;
+      me = where[i];
+      npcmps[me]++;
+    }
+
+    i = cind[first++];
+    k = perm[i];
+    j = todo[k] = todo[--nleft];
+    perm[j] = k;
+
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      k = adjncy[j];
+      if (where[k] == me && !touched[k]) {
+        cind[last++] = k;
+        touched[k] = 1;
+      }
+    }
+  }
+  cptr[++ncmps] = first;
+
+  /* printf("I found %d components, for this %d-way partition\n", ncmps, nparts); */
+
+  if (ncmps > nparts) { /* There are more components than processors */
+    cand = (KeyValueType *)GKmalloc(nparts*sizeof(KeyValueType), "EliminateSubDomainEdges: cand");
+
+    /* First determine the partition sizes and max allowed load imbalance */
+    for (i=0; i<nvtxs; i++) 
+      pwgts[where[i]] += vwgt[i];
+    tvwgt = idxsum(nparts, pwgts);
+    for (i=0; i<nparts; i++)
+      maxpwgt[i] = ubfactor*tpwgts[i]*tvwgt;
+
+    deltawgt = tvwgt/(100*nparts);
+    deltawgt = 5;
+
+    for (i=0; i<ncmps; i++) {
+      me = where[cind[cptr[i]]];  /* Get the domain of this component */
+      if (npcmps[me] == 1)
+        continue;  /* Skip it because it is contigous */
+
+      /*printf("Trying to move %d from %d\n", i, me); */
+
+      /* Determine the connectivity */
+      idxset(nparts, 0, cpvec);
+      for (cwgt=0, j=cptr[i]; j<cptr[i+1]; j++) {
+        ii = cind[j];
+        cwgt += vwgt[ii];
+        for (jj=xadj[ii]; jj<xadj[ii+1]; jj++) {
+          other = where[adjncy[jj]];
+          if (me != other)
+            cpvec[other] += adjwgt[jj];
+        }
+      }
+
+      /*printf("\tCmp weight: %d\n", cwgt);*/
+
+      if (cwgt > .30*pwgts[me])
+        continue;  /* Skip the component if it is over 30% of the weight */
+
+      for (ncand=0, j=0; j<nparts; j++) {
+        if (cpvec[j] > 0) {
+          cand[ncand].key = -cpvec[j];
+          cand[ncand++].val = j;
+        }
+      }
+      if (ncand == 0)
+        continue;
+
+      ikeysort(ncand, cand);
+
+      target = -1;
+      for (j=0; j<ncand; j++) {
+        k = cand[j].val;
+        if (cwgt < deltawgt || pwgts[k] + cwgt < maxpwgt[k]) {
+          target = k;
+          break;
+        }
+      }
+
+      /*printf("\tMoving it to %d [%d]\n", target, cpvec[target]);*/
+
+      if (target != -1) {
+        /* Assign all the vertices of 'me' to 'target' and update data structures */
+        pwgts[me] -= cwgt;
+        pwgts[target] += cwgt;
+        npcmps[me]--;
+
+        for (j=cptr[i]; j<cptr[i+1]; j++) 
+          where[cind[j]] = target;
+
+        graph->mincut -= cpvec[target];
+        recompute = 1;
+      }
+    }
+
+    free(cand);
+  }
+
+  if (recompute) {
+    int ttlv;
+    idxtype *marker;
+
+    marker = idxset(nparts, -1, cpvec);
+    for (ttlv=0, i=0; i<nvtxs; i++) {
+      marker[where[i]] = i;
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        if (marker[where[adjncy[j]]] != i) {
+          ttlv += graph->vsize[i];
+          marker[where[adjncy[j]]] = i;
+        }
+      }
+    }
+    graph->minvol = ttlv;
+  }
+
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+
+}
+
diff --git a/Metis/kwayvolrefine.c b/Metis/kwayvolrefine.c
new file mode 100644
index 0000000000..2c4e56ed0c
--- /dev/null
+++ b/Metis/kwayvolrefine.c
@@ -0,0 +1,460 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * kwayvolrefine.c
+ *
+ * This file contains the driving routines for multilevel k-way refinement
+ *
+ * Started 7/28/97
+ * George
+ *
+ * $Id: kwayvolrefine.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function is the entry point of refinement
+**************************************************************************/
+void RefineVolKWay(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, int nparts, 
+                   float *tpwgts, float ubfactor)
+{
+  int i, nlevels;
+  GraphType *ptr;
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr));
+
+  /* Take care any non-contiguity */
+  if (ctrl->RType == RTYPE_KWAYRANDOM_MCONN) {
+    ComputeVolKWayPartitionParams(ctrl, graph, nparts);
+    EliminateVolComponents(ctrl, graph, nparts, tpwgts, 1.25);
+    EliminateVolSubDomainEdges(ctrl, graph, nparts, tpwgts);
+    EliminateVolComponents(ctrl, graph, nparts, tpwgts, 1.25);
+  }
+
+
+  /* Determine how many levels are there */
+  for (ptr=graph, nlevels=0; ptr!=orggraph; ptr=ptr->finer, nlevels++); 
+
+  /* Compute the parameters of the coarsest graph */
+  ComputeVolKWayPartitionParams(ctrl, graph, nparts);
+
+  for (i=0; ;i++) {
+    /*PrintSubDomainGraph(graph, nparts, graph->where);*/
+    MALLOC_CHECK(NULL);
+    IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr));
+
+    if (2*i >= nlevels && !IsBalanced(graph->pwgts, nparts, tpwgts, 1.04*ubfactor)) {
+      ComputeVolKWayBalanceBoundary(ctrl, graph, nparts);
+      switch (ctrl->RType) {
+        case RTYPE_KWAYRANDOM:
+          Greedy_KWayVolBalance(ctrl, graph, nparts, tpwgts, ubfactor, 1); 
+          break;
+        case RTYPE_KWAYRANDOM_MCONN:
+          Greedy_KWayVolBalanceMConn(ctrl, graph, nparts, tpwgts, ubfactor, 1); 
+          break;
+      }
+      ComputeVolKWayBoundary(ctrl, graph, nparts);
+    }
+
+    switch (ctrl->RType) {
+      case RTYPE_KWAYRANDOM:
+        Random_KWayVolRefine(ctrl, graph, nparts, tpwgts, ubfactor, 10, 0); 
+        break;
+      case RTYPE_KWAYRANDOM_MCONN:
+        Random_KWayVolRefineMConn(ctrl, graph, nparts, tpwgts, ubfactor, 10, 0); 
+        break;
+    }
+    IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr));
+
+    if (graph == orggraph)
+      break;
+
+    GKfree(&graph->gdata, LTERM);  /* Deallocate the graph related arrays */
+
+    graph = graph->finer;
+
+    IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr));
+    ProjectVolKWayPartition(ctrl, graph, nparts);
+    IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr));
+  }
+
+  if (!IsBalanced(graph->pwgts, nparts, tpwgts, ubfactor)) {
+    ComputeVolKWayBalanceBoundary(ctrl, graph, nparts);
+    switch (ctrl->RType) {
+      case RTYPE_KWAYRANDOM:
+        Greedy_KWayVolBalance(ctrl, graph, nparts, tpwgts, ubfactor, 8); 
+        Random_KWayVolRefine(ctrl, graph, nparts, tpwgts, ubfactor, 10, 0); 
+        break;
+      case RTYPE_KWAYRANDOM_MCONN:
+        Greedy_KWayVolBalanceMConn(ctrl, graph, nparts, tpwgts, ubfactor, 8); 
+        Random_KWayVolRefineMConn(ctrl, graph, nparts, tpwgts, ubfactor, 10, 0); 
+        break;
+    }
+  }
+
+  EliminateVolComponents(ctrl, graph, nparts, tpwgts, ubfactor); 
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr));
+}
+
+
+
+/*************************************************************************
+* This function allocates memory for k-way edge refinement
+**************************************************************************/
+void AllocateVolKWayPartitionMemory(CtrlType *ctrl, GraphType *graph, int nparts)
+{
+  int nvtxs, pad64;
+
+  nvtxs = graph->nvtxs;
+
+  pad64 = (3*nvtxs+nparts)%2;
+
+  graph->rdata = idxmalloc(3*nvtxs+nparts+(sizeof(VRInfoType)/sizeof(idxtype))*nvtxs+pad64, "AllocateVolKWayPartitionMemory: rdata");
+  graph->pwgts          = graph->rdata;
+  graph->where          = graph->rdata + nparts;
+  graph->bndptr         = graph->rdata + nvtxs + nparts;
+  graph->bndind         = graph->rdata + 2*nvtxs + nparts;
+  graph->vrinfo          = (VRInfoType *)(graph->rdata + 3*nvtxs+nparts + pad64);
+
+}
+
+
+
+/*************************************************************************
+* This function computes the initial id/ed 
+**************************************************************************/
+void ComputeVolKWayPartitionParams(CtrlType *ctrl, GraphType *graph, int nparts)
+{
+  int i, ii, j, k, kk, l, nvtxs, nbnd, mincut, minvol, me, other, pid; 
+  idxtype *xadj, *vwgt, *adjncy, *adjwgt, *pwgts, *where;
+  VRInfoType *rinfo, *myrinfo, *orinfo;
+  VEDegreeType *myedegrees, *oedegrees;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  vwgt = graph->vwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  where = graph->where;
+  pwgts = idxset(nparts, 0, graph->pwgts);
+  rinfo = graph->vrinfo;
+
+
+  /*------------------------------------------------------------
+  / Compute now the id/ed degrees
+  /------------------------------------------------------------*/
+  ctrl->wspace.cdegree = 0;
+  mincut = 0;
+  for (i=0; i<nvtxs; i++) {
+    me = where[i];
+    pwgts[me] += vwgt[i];
+
+    myrinfo = rinfo+i;
+    myrinfo->id = myrinfo->ed = myrinfo->nid = myrinfo->ndegrees = 0;
+    myrinfo->edegrees = NULL;
+
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      if (me == where[adjncy[j]]) {
+        myrinfo->id += adjwgt[j];
+        myrinfo->nid++;
+      }
+    }
+    myrinfo->ed = graph->adjwgtsum[i] - myrinfo->id;
+
+    mincut += myrinfo->ed;
+
+    /* Time to compute the particular external degrees */
+    if (myrinfo->ed > 0) { 
+      myedegrees = myrinfo->edegrees = ctrl->wspace.vedegrees+ctrl->wspace.cdegree;
+      ctrl->wspace.cdegree += xadj[i+1]-xadj[i];
+
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        other = where[adjncy[j]];
+        if (me != other) {
+          for (k=0; k<myrinfo->ndegrees; k++) {
+            if (myedegrees[k].pid == other) {
+              myedegrees[k].ed += adjwgt[j];
+              myedegrees[k].ned++;
+              break;
+            }
+          }
+          if (k == myrinfo->ndegrees) {
+            myedegrees[myrinfo->ndegrees].gv = 0;
+            myedegrees[myrinfo->ndegrees].pid = other;
+            myedegrees[myrinfo->ndegrees].ed = adjwgt[j];
+            myedegrees[myrinfo->ndegrees++].ned = 1;
+          }
+        }
+      }
+
+      ASSERT(myrinfo->ndegrees <= xadj[i+1]-xadj[i]);
+    }
+  }
+  graph->mincut = mincut/2;
+
+
+  ComputeKWayVolGains(ctrl, graph, nparts);
+
+}
+
+
+
+/*************************************************************************
+* This function computes the initial id/ed 
+**************************************************************************/
+void ComputeKWayVolGains(CtrlType *ctrl, GraphType *graph, int nparts)
+{
+  int i, ii, j, k, kk, l, nvtxs, me, other, pid, myndegrees; 
+  idxtype *xadj, *vsize, *adjncy, *adjwgt, *where, *bndind, *bndptr, *ophtable;
+  VRInfoType *rinfo, *myrinfo, *orinfo;
+  VEDegreeType *myedegrees, *oedegrees;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  vsize = graph->vsize;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  where = graph->where;
+  bndind = graph->bndind;
+  bndptr = idxset(nvtxs, -1, graph->bndptr);
+  rinfo = graph->vrinfo;
+
+  ophtable = idxset(nparts, -1, idxwspacemalloc(ctrl, nparts));
+
+  /*------------------------------------------------------------
+  / Compute now the iv/ev degrees
+  /------------------------------------------------------------*/
+  graph->minvol = graph->nbnd = 0;
+  for (i=0; i<nvtxs; i++) {
+    myrinfo = rinfo+i;
+    myrinfo->gv = -MAXIDX;
+
+    if (myrinfo->ndegrees > 0) {
+      me = where[i];
+      myedegrees = myrinfo->edegrees;
+      myndegrees = myrinfo->ndegrees;
+
+      graph->minvol += myndegrees*vsize[i];
+
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        ii = adjncy[j];
+        other = where[ii];
+        orinfo = rinfo+ii;
+        oedegrees = orinfo->edegrees;
+
+        for (k=0; k<orinfo->ndegrees; k++) 
+          ophtable[oedegrees[k].pid] = k;
+        ophtable[other] = 1;  /* this is to simplify coding */
+
+        if (me == other) {
+          /* Find which domains 'i' is connected and 'ii' is not and update their gain */
+          for (k=0; k<myndegrees; k++) {
+            if (ophtable[myedegrees[k].pid] == -1)
+              myedegrees[k].gv -= vsize[ii];
+          }
+        }
+        else {
+          ASSERT(ophtable[me] != -1);
+
+          if (oedegrees[ophtable[me]].ned == 1) { /* I'm the only connection of 'ii' in 'me' */
+            /* Increase the gains for all the common domains between 'i' and 'ii' */
+            for (k=0; k<myndegrees; k++) {
+              if (ophtable[myedegrees[k].pid] != -1) 
+                myedegrees[k].gv += vsize[ii];
+            }
+          }
+          else {
+            /* Find which domains 'i' is connected and 'ii' is not and update their gain */
+            for (k=0; k<myndegrees; k++) {
+              if (ophtable[myedegrees[k].pid] == -1) 
+                myedegrees[k].gv -= vsize[ii];
+            }
+          }
+        }
+
+        for (kk=0; kk<orinfo->ndegrees; kk++) 
+          ophtable[oedegrees[kk].pid] = -1;
+        ophtable[other] = -1;
+      }
+
+      /* Compute the max vgain */
+      for (k=0; k<myndegrees; k++) {
+        if (myedegrees[k].gv > myrinfo->gv)
+          myrinfo->gv = myedegrees[k].gv;
+      }
+    }
+
+    if (myrinfo->ed > 0 && myrinfo->id == 0) 
+      myrinfo->gv += vsize[i];
+
+    if (myrinfo->gv >= 0 || myrinfo->ed-myrinfo->id >= 0)
+      BNDInsert(graph->nbnd, bndind, bndptr, i);
+  }
+
+  idxwspacefree(ctrl, nparts);
+
+}
+
+
+
+/*************************************************************************
+* This function projects a partition, and at the same time computes the
+* parameters for refinement.
+**************************************************************************/
+void ProjectVolKWayPartition(CtrlType *ctrl, GraphType *graph, int nparts)
+{
+  int i, j, k, nvtxs, me, other, istart, iend, ndegrees;
+  idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum;
+  idxtype *cmap, *where;
+  idxtype *cwhere;
+  GraphType *cgraph;
+  VRInfoType *crinfo, *rinfo, *myrinfo;
+  VEDegreeType *myedegrees;
+  idxtype *htable;
+
+  cgraph = graph->coarser;
+  cwhere = cgraph->where;
+  crinfo = cgraph->vrinfo;
+
+  nvtxs = graph->nvtxs;
+  cmap = graph->cmap;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+  adjwgtsum = graph->adjwgtsum;
+
+  AllocateVolKWayPartitionMemory(ctrl, graph, nparts);
+  where = graph->where;
+  rinfo = graph->vrinfo;
+
+  /* Go through and project partition and compute id/ed for the nodes */
+  for (i=0; i<nvtxs; i++) {
+    k = cmap[i];
+    where[i] = cwhere[k];
+    cmap[i] = crinfo[k].ed;  /* For optimization */
+  }
+
+  htable = idxset(nparts, -1, idxwspacemalloc(ctrl, nparts));
+
+  ctrl->wspace.cdegree = 0;
+  for (i=0; i<nvtxs; i++) {
+    me = where[i];
+
+    myrinfo = rinfo+i;
+    myrinfo->id = myrinfo->ed = myrinfo->nid = myrinfo->ndegrees = 0;
+    myrinfo->edegrees = NULL;
+
+    myrinfo->id = adjwgtsum[i];
+    myrinfo->nid = xadj[i+1]-xadj[i];
+
+    if (cmap[i] > 0) { /* If it is an interface node. Note cmap[i] = crinfo[cmap[i]].ed */
+      istart = xadj[i];
+      iend = xadj[i+1];
+
+      myedegrees = myrinfo->edegrees = ctrl->wspace.vedegrees+ctrl->wspace.cdegree;
+      ctrl->wspace.cdegree += iend-istart;
+
+      ndegrees = 0;
+      for (j=istart; j<iend; j++) {
+        other = where[adjncy[j]];
+        if (me != other) {
+          myrinfo->ed += adjwgt[j];
+          myrinfo->nid--;
+          if ((k = htable[other]) == -1) {
+            htable[other] = ndegrees;
+            myedegrees[ndegrees].gv = 0;
+            myedegrees[ndegrees].pid = other;
+            myedegrees[ndegrees].ed = adjwgt[j];
+            myedegrees[ndegrees++].ned = 1;
+          }
+          else {
+            myedegrees[k].ed += adjwgt[j];
+            myedegrees[k].ned++;
+          }
+        }
+      }
+      myrinfo->id -= myrinfo->ed;
+
+      /* Remove space for edegrees if it was interior */
+      if (myrinfo->ed == 0) { 
+        myrinfo->edegrees = NULL;
+        ctrl->wspace.cdegree -= iend-istart;
+      }
+      else {
+        myrinfo->ndegrees = ndegrees;
+
+        for (j=0; j<ndegrees; j++)
+          htable[myedegrees[j].pid] = -1;
+      }
+    }
+  }
+
+  ComputeKWayVolGains(ctrl, graph, nparts);
+
+  idxcopy(nparts, cgraph->pwgts, graph->pwgts);
+  graph->mincut = cgraph->mincut;
+
+  FreeGraph(graph->coarser);
+  graph->coarser = NULL;
+
+  idxwspacefree(ctrl, nparts);
+
+}
+
+
+
+/*************************************************************************
+* This function computes the boundary definition for balancing
+**************************************************************************/
+void ComputeVolKWayBoundary(CtrlType *ctrl, GraphType *graph, int nparts)
+{
+  int i, nvtxs, nbnd;
+  idxtype *bndind, *bndptr;
+
+  nvtxs = graph->nvtxs;
+  bndind = graph->bndind;
+  bndptr = idxset(nvtxs, -1, graph->bndptr);
+
+
+  /*------------------------------------------------------------
+  / Compute the new boundary
+  /------------------------------------------------------------*/
+  nbnd = 0;
+  for (i=0; i<nvtxs; i++) {
+    if (graph->vrinfo[i].gv >=0 || graph->vrinfo[i].ed-graph->vrinfo[i].id >= 0) 
+      BNDInsert(nbnd, bndind, bndptr, i);
+  }
+
+  graph->nbnd = nbnd;
+}
+
+/*************************************************************************
+* This function computes the boundary definition for balancing
+**************************************************************************/
+void ComputeVolKWayBalanceBoundary(CtrlType *ctrl, GraphType *graph, int nparts)
+{
+  int i, nvtxs, nbnd;
+  idxtype *bndind, *bndptr;
+
+  nvtxs = graph->nvtxs;
+  bndind = graph->bndind;
+  bndptr = idxset(nvtxs, -1, graph->bndptr);
+
+
+  /*------------------------------------------------------------
+  / Compute the new boundary
+  /------------------------------------------------------------*/
+  nbnd = 0;
+  for (i=0; i<nvtxs; i++) {
+    if (graph->vrinfo[i].ed > 0) 
+      BNDInsert(nbnd, bndind, bndptr, i);
+  }
+
+  graph->nbnd = nbnd;
+}
+
diff --git a/Metis/macros.h b/Metis/macros.h
new file mode 100644
index 0000000000..16634f73b4
--- /dev/null
+++ b/Metis/macros.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * macros.h
+ *
+ * This file contains macros used in multilevel
+ *
+ * Started 9/25/94
+ * George
+ *
+ * $Id: macros.h,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+
+/*************************************************************************
+* The following macro returns a random number in the specified range
+**************************************************************************/
+#ifdef __VC__
+#define RandomInRange(u) ((rand()>>3)%(u))
+#define RandomInRangeFast(u) ((rand()>>3)%(u))
+#else
+#define RandomInRange(u) ((int)(drand48()*((double)(u))))
+#define RandomInRangeFast(u) ((rand()>>3)%(u))
+#endif
+
+
+
+#define amax(a, b) ((a) >= (b) ? (a) : (b))
+#define amin(a, b) ((a) >= (b) ? (b) : (a))
+
+#define AND(a, b) ((a) < 0 ? ((-(a))&(b)) : ((a)&(b)))
+#define OR(a, b) ((a) < 0 ? -((-(a))|(b)) : ((a)|(b)))
+#define XOR(a, b) ((a) < 0 ? -((-(a))^(b)) : ((a)^(b)))
+
+#define SWAP(a, b, tmp)  \
+                 do {(tmp) = (a); (a) = (b); (b) = (tmp);} while(0) 
+
+#define INC_DEC(a, b, val) \
+                 do {(a) += (val); (b) -= (val);} while(0)
+
+
+#define scopy(n, a, b) (float *)memcpy((void *)(b), (void *)(a), sizeof(float)*(n))
+#define idxcopy(n, a, b) (idxtype *)memcpy((void *)(b), (void *)(a), sizeof(idxtype)*(n)) 
+
+#define HASHFCT(key, size) ((key)%(size))
+
+
+/*************************************************************************
+* Timer macros
+**************************************************************************/
+#define cleartimer(tmr) (tmr = 0.0)
+#define starttimer(tmr) (tmr -= seconds())
+#define stoptimer(tmr) (tmr += seconds())
+#define gettimer(tmr) (tmr)
+
+
+/*************************************************************************
+* This macro is used to handle dbglvl
+**************************************************************************/
+#define IFSET(a, flag, cmd) if ((a)&(flag)) (cmd);
+
+/*************************************************************************
+* These macros are used for debuging memory leaks
+**************************************************************************/
+#ifdef DMALLOC
+#define imalloc(n, msg) (malloc(sizeof(int)*(n)))
+#define fmalloc(n, msg) (malloc(sizeof(float)*(n)))
+#define idxmalloc(n, msg) (malloc(sizeof(idxtype)*(n)))
+#define ismalloc(n, val, msg) (iset((n), (val), malloc(sizeof(int)*(n))))
+#define idxsmalloc(n, val, msg) (idxset((n), (val), malloc(sizeof(idxtype)*(n))))
+#define GKmalloc(a, b) (malloc((a)))
+#endif
+
+#ifdef DMALLOC
+#   define MALLOC_CHECK(ptr)                                          \
+    if (malloc_verify((ptr)) == DMALLOC_VERIFY_ERROR) {  \
+        printf("***MALLOC_CHECK failed on line %d of file %s: " #ptr "\n", \
+              __LINE__, __FILE__);                               \
+        abort();                                                \
+    }
+#else
+#   define MALLOC_CHECK(ptr) ;
+#endif 
+
+
+
+/*************************************************************************
+* This macro converts a length array in a CSR one
+**************************************************************************/
+#define MAKECSR(i, n, a) \
+   do { \
+     for (i=1; i<n; i++) a[i] += a[i-1]; \
+     for (i=n; i>0; i--) a[i] = a[i-1]; \
+     a[0] = 0; \
+   } while(0) 
+
+
+/*************************************************************************
+* These macros insert and remove nodes from the boundary list
+**************************************************************************/
+#define BNDInsert(nbnd, bndind, bndptr, vtx) \
+   do { \
+     ASSERT(bndptr[vtx] == -1); \
+     bndind[nbnd] = vtx; \
+     bndptr[vtx] = nbnd++;\
+   } while(0) 
+
+#define BNDDelete(nbnd, bndind, bndptr, vtx) \
+   do { \
+     ASSERT(bndptr[vtx] != -1); \
+     bndind[bndptr[vtx]] = bndind[--nbnd]; \
+     bndptr[bndind[nbnd]] = bndptr[vtx]; \
+     bndptr[vtx] = -1; \
+   } while(0) 
+
+
+
+/*************************************************************************
+* These are debugging macros
+**************************************************************************/
+#ifdef DEBUG
+#   define ASSERT(expr)                                          \
+    if (!(expr)) {                                               \
+        printf("***ASSERTION failed on line %d of file %s: " #expr "\n", \
+              __LINE__, __FILE__);                               \
+        abort();                                                \
+    }
+#else
+#   define ASSERT(expr) ;
+#endif 
+
+#ifdef DEBUG
+#   define ASSERTP(expr, msg)                                          \
+    if (!(expr)) {                                               \
+        printf("***ASSERTION failed on line %d of file %s: " #expr "\n", \
+              __LINE__, __FILE__);                               \
+        printf msg ; \
+        abort();                                                \
+    }
+#else
+#   define ASSERTP(expr, msg) ;
+#endif 
diff --git a/Metis/match.c b/Metis/match.c
new file mode 100644
index 0000000000..c1434576a2
--- /dev/null
+++ b/Metis/match.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * match.c
+ *
+ * This file contains the code that computes matchings and creates the next
+ * level coarse graph.
+ *
+ * Started 7/23/97
+ * George
+ *
+ * $Id: match.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function finds a matching using the HEM heuristic
+**************************************************************************/
+void Match_RM(CtrlType *ctrl, GraphType *graph)
+{
+  int i, ii, j, nvtxs, cnvtxs, maxidx;
+  idxtype *xadj, *vwgt, *adjncy, *adjwgt;
+  idxtype *match, *cmap, *perm;
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr));
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  vwgt = graph->vwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  cmap = graph->cmap;
+  match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs));
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  RandomPermute(nvtxs, perm, 1);
+
+  cnvtxs = 0;
+  for (ii=0; ii<nvtxs; ii++) {
+    i = perm[ii];
+
+    if (match[i] == UNMATCHED) {  /* Unmatched */
+      maxidx = i;
+
+      /* Find a random matching, subject to maxvwgt constraints */
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        if (match[adjncy[j]] == UNMATCHED && vwgt[i]+vwgt[adjncy[j]] <= ctrl->maxvwgt) {
+          maxidx = adjncy[j];
+          break;
+        }
+      }
+
+      cmap[i] = cmap[maxidx] = cnvtxs++;
+      match[i] = maxidx;
+      match[maxidx] = i;
+    }
+  }
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr));
+
+  CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm);
+
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+/*************************************************************************
+* This function finds a matching using the HEM heuristic
+**************************************************************************/
+void Match_RM_NVW(CtrlType *ctrl, GraphType *graph)
+{
+  int i, ii, j, nvtxs, cnvtxs, maxidx;
+  idxtype *xadj, *adjncy;
+  idxtype *match, *cmap, *perm;
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr));
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+
+  cmap = graph->cmap;
+  match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs));
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  RandomPermute(nvtxs, perm, 1);
+
+  cnvtxs = 0;
+  for (ii=0; ii<nvtxs; ii++) {
+    i = perm[ii];
+
+    if (match[i] == UNMATCHED) {  /* Unmatched */
+      maxidx = i;
+
+      /* Find a random matching, subject to maxvwgt constraints */
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        if (match[adjncy[j]] == UNMATCHED) {
+          maxidx = adjncy[j];
+          break;
+        }
+      }
+
+      cmap[i] = cmap[maxidx] = cnvtxs++;
+      match[i] = maxidx;
+      match[maxidx] = i;
+    }
+  }
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr));
+
+  CreateCoarseGraph_NVW(ctrl, graph, cnvtxs, match, perm);
+
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+
+/*************************************************************************
+* This function finds a matching using the HEM heuristic
+**************************************************************************/
+void Match_HEM(CtrlType *ctrl, GraphType *graph)
+{
+  int i, ii, j, k, nvtxs, cnvtxs, maxidx, maxwgt;
+  idxtype *xadj, *vwgt, *adjncy, *adjwgt;
+  idxtype *match, *cmap, *perm;
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr));
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  vwgt = graph->vwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  cmap = graph->cmap;
+  match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs));
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  RandomPermute(nvtxs, perm, 1);
+
+  cnvtxs = 0;
+  for (ii=0; ii<nvtxs; ii++) {
+    i = perm[ii];
+
+    if (match[i] == UNMATCHED) {  /* Unmatched */
+      maxidx = i;
+      maxwgt = 0;
+
+      /* Find a heavy-edge matching, subject to maxvwgt constraints */
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        k = adjncy[j];
+        if (match[k] == UNMATCHED && maxwgt < adjwgt[j] && vwgt[i]+vwgt[k] <= ctrl->maxvwgt) {
+          maxwgt = adjwgt[j];
+          maxidx = adjncy[j];
+        }
+      }
+
+      cmap[i] = cmap[maxidx] = cnvtxs++;
+      match[i] = maxidx;
+      match[maxidx] = i;
+    }
+  }
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr));
+
+  CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm);
+
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+
+/*************************************************************************
+* This function finds a matching using the HEM heuristic
+**************************************************************************/
+void Match_SHEM(CtrlType *ctrl, GraphType *graph)
+{
+  int i, ii, j, k, nvtxs, cnvtxs, maxidx, maxwgt, avgdegree;
+  idxtype *xadj, *vwgt, *adjncy, *adjwgt;
+  idxtype *match, *cmap, *degrees, *perm, *tperm;
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr));
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  vwgt = graph->vwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  cmap = graph->cmap;
+  match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs));
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  tperm = idxwspacemalloc(ctrl, nvtxs);
+  degrees = idxwspacemalloc(ctrl, nvtxs);
+
+  RandomPermute(nvtxs, tperm, 1);
+  avgdegree = 0.7*(xadj[nvtxs]/nvtxs);
+  for (i=0; i<nvtxs; i++) 
+    degrees[i] = (xadj[i+1]-xadj[i] > avgdegree ? avgdegree : xadj[i+1]-xadj[i]);
+  BucketSortKeysInc(nvtxs, avgdegree, degrees, tperm, perm);
+
+  cnvtxs = 0;
+
+  /* Take care any islands. Islands are matched with non-islands due to coarsening */
+  for (ii=0; ii<nvtxs; ii++) {
+    i = perm[ii];
+
+    if (match[i] == UNMATCHED) {  /* Unmatched */
+      if (xadj[i] < xadj[i+1])
+        break;
+
+      maxidx = i;
+      for (j=nvtxs-1; j>ii; j--) {
+        k = perm[j];
+        if (match[k] == UNMATCHED && xadj[k] < xadj[k+1]) {
+          maxidx = k;
+          break;
+        }
+      }
+
+      cmap[i] = cmap[maxidx] = cnvtxs++;
+      match[i] = maxidx;
+      match[maxidx] = i;
+    }
+  }
+
+  /* Continue with normal matching */
+  for (; ii<nvtxs; ii++) {
+    i = perm[ii];
+
+    if (match[i] == UNMATCHED) {  /* Unmatched */
+      maxidx = i;
+      maxwgt = 0;
+
+      /* Find a heavy-edge matching, subject to maxvwgt constraints */
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        if (match[adjncy[j]] == UNMATCHED && maxwgt < adjwgt[j] && vwgt[i]+vwgt[adjncy[j]] <= ctrl->maxvwgt) {
+          maxwgt = adjwgt[j];
+          maxidx = adjncy[j];
+        }
+      }
+
+      cmap[i] = cmap[maxidx] = cnvtxs++;
+      match[i] = maxidx;
+      match[maxidx] = i;
+    }
+  }
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr));
+
+  idxwspacefree(ctrl, nvtxs);  /* degrees */
+  idxwspacefree(ctrl, nvtxs);  /* tperm */
+
+  CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm);
+
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+}
+
diff --git a/Metis/mbalance.c b/Metis/mbalance.c
new file mode 100644
index 0000000000..b97938e87e
--- /dev/null
+++ b/Metis/mbalance.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * mbalance.c
+ *
+ * This file contains code that is used to forcefully balance either
+ * bisections or k-sections
+ *
+ * Started 7/29/97
+ * George
+ *
+ * $Id: mbalance.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function is the entry point of the bisection balancing algorithms.
+**************************************************************************/
+void MocBalance2Way(CtrlType *ctrl, GraphType *graph, float *tpwgts, float lbfactor)
+{
+
+  if (Compute2WayHLoadImbalance(graph->ncon, graph->npwgts, tpwgts) < lbfactor)
+    return;
+
+  MocGeneral2WayBalance(ctrl, graph, tpwgts, lbfactor);
+
+}
+
+
+/*************************************************************************
+* This function performs an edge-based FM refinement
+**************************************************************************/
+void MocGeneral2WayBalance(CtrlType *ctrl, GraphType *graph, float *tpwgts, float lbfactor)
+{
+  int i, ii, j, k, l, kwgt, nvtxs, ncon, nbnd, nswaps, from, to, pass, me, limit, tmp, cnum;
+  idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind;
+  idxtype *moved, *swaps, *perm, *qnum;
+  float *nvwgt, *npwgts, mindiff[MAXNCON], origbal, minbal, newbal;
+  PQueueType parts[MAXNCON][2];
+  int higain, oldgain, mincut, newcut, mincutorder;
+  int qsizes[MAXNCON][2];
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  xadj = graph->xadj;
+  nvwgt = graph->nvwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+  where = graph->where;
+  id = graph->id;
+  ed = graph->ed;
+  npwgts = graph->npwgts;
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+
+  moved = idxwspacemalloc(ctrl, nvtxs);
+  swaps = idxwspacemalloc(ctrl, nvtxs);
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  qnum = idxwspacemalloc(ctrl, nvtxs);
+
+  limit = amin(amax(0.01*nvtxs, 15), 100);
+
+  /* Initialize the queues */
+  for (i=0; i<ncon; i++) {
+    PQueueInit(ctrl, &parts[i][0], nvtxs, PLUS_GAINSPAN+1);
+    PQueueInit(ctrl, &parts[i][1], nvtxs, PLUS_GAINSPAN+1);
+    qsizes[i][0] = qsizes[i][1] = 0;
+  }
+
+  for (i=0; i<nvtxs; i++) {
+    qnum[i] = samax(ncon, nvwgt+i*ncon);
+    qsizes[qnum[i]][where[i]]++;
+  }
+
+/*
+  printf("Weight Distribution:    \t");
+  for (i=0; i<ncon; i++) 
+    printf(" [%d %d]", qsizes[i][0], qsizes[i][1]); 
+  printf("\n");
+*/
+
+  for (from=0; from<2; from++) {
+    for (j=0; j<ncon; j++) {
+      if (qsizes[j][from] == 0) {
+        for (i=0; i<nvtxs; i++) {
+          if (where[i] != from)
+            continue;
+
+          k = samax2(ncon, nvwgt+i*ncon);
+          if (k == j && qsizes[qnum[i]][from] > qsizes[j][from] && nvwgt[i*ncon+qnum[i]] < 1.3*nvwgt[i*ncon+j]) {
+            qsizes[qnum[i]][from]--;
+            qsizes[j][from]++;
+            qnum[i] = j;
+          }
+        }
+      }
+    }
+  }
+
+/*
+  printf("Weight Distribution (after):\t ");
+  for (i=0; i<ncon; i++) 
+    printf(" [%d %d]", qsizes[i][0], qsizes[i][1]); 
+  printf("\n");
+*/
+
+
+
+  for (i=0; i<ncon; i++) 
+    mindiff[i] = fabs(tpwgts[0]-npwgts[i]);
+  minbal = origbal = Compute2WayHLoadImbalance(ncon, npwgts, tpwgts);
+  newcut = mincut = graph->mincut;
+  mincutorder = -1;
+
+  if (ctrl->dbglvl&DBG_REFINE) {
+    printf("Parts: [");
+    for (l=0; l<ncon; l++)
+      printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
+    printf("] T[%.3f %.3f], Nv-Nb[%5d, %5d]. ICut: %6d, LB: %.3f [B]\n", tpwgts[0], tpwgts[1], graph->nvtxs, graph->nbnd, graph->mincut, origbal);
+  }
+
+  idxset(nvtxs, -1, moved);
+
+  ASSERT(ComputeCut(graph, where) == graph->mincut);
+  ASSERT(CheckBnd(graph));
+
+  /* Insert all nodes in the priority queues */
+  nbnd = graph->nbnd;
+  RandomPermute(nvtxs, perm, 1);
+  for (ii=0; ii<nvtxs; ii++) {
+    i = perm[ii];
+    PQueueInsert(&parts[qnum[i]][where[i]], i, ed[i]-id[i]);
+  }
+
+  for (nswaps=0; nswaps<nvtxs; nswaps++) {
+    if (minbal < lbfactor)
+      break;
+
+    SelectQueue(ncon, npwgts, tpwgts, &from, &cnum, parts);
+    to = (from+1)%2;
+
+    if (from == -1 || (higain = PQueueGetMax(&parts[cnum][from])) == -1)
+      break;
+
+    saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
+    saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1);
+    newcut -= (ed[higain]-id[higain]);
+    newbal = Compute2WayHLoadImbalance(ncon, npwgts, tpwgts);
+
+    if (newbal < minbal || (newbal == minbal && 
+        (newcut < mincut || (newcut == mincut && BetterBalance(ncon, npwgts, tpwgts, mindiff))))) {
+      mincut = newcut;
+      minbal = newbal;
+      mincutorder = nswaps;
+      for (i=0; i<ncon; i++)
+        mindiff[i] = fabs(tpwgts[0]-npwgts[i]);
+    }
+    else if (nswaps-mincutorder > limit) { /* We hit the limit, undo last move */
+      newcut += (ed[higain]-id[higain]);
+      saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1);
+      saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
+      break;
+    }
+
+    where[higain] = to;
+    moved[higain] = nswaps;
+    swaps[nswaps] = higain;
+
+    if (ctrl->dbglvl&DBG_MOVEINFO) {
+      printf("Moved %6d from %d(%d). Gain: %5d, Cut: %5d, NPwgts: ", higain, from, cnum, ed[higain]-id[higain], newcut);
+      for (l=0; l<ncon; l++) 
+        printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
+      printf(", %.3f LB: %.3f\n", minbal, newbal);
+    }
+
+
+    /**************************************************************
+    * Update the id[i]/ed[i] values of the affected nodes
+    ***************************************************************/
+    SWAP(id[higain], ed[higain], tmp);
+    if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) 
+      BNDDelete(nbnd, bndind,  bndptr, higain);
+    if (ed[higain] > 0 && bndptr[higain] == -1)
+      BNDInsert(nbnd, bndind,  bndptr, higain);
+
+    for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+      k = adjncy[j];
+      oldgain = ed[k]-id[k];
+
+      kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
+      INC_DEC(id[k], ed[k], kwgt);
+
+      /* Update the queue position */
+      if (moved[k] == -1)
+        PQueueUpdate(&parts[qnum[k]][where[k]], k, oldgain, ed[k]-id[k]);
+
+      /* Update its boundary information */
+      if (ed[k] == 0 && bndptr[k] != -1) 
+        BNDDelete(nbnd, bndind, bndptr, k);
+      else if (ed[k] > 0 && bndptr[k] == -1)  
+        BNDInsert(nbnd, bndind, bndptr, k);
+    }
+  }
+
+
+
+  /****************************************************************
+  * Roll back computations
+  *****************************************************************/
+  for (nswaps--; nswaps>mincutorder; nswaps--) {
+    higain = swaps[nswaps];
+
+    to = where[higain] = (where[higain]+1)%2;
+    SWAP(id[higain], ed[higain], tmp);
+    if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1])
+      BNDDelete(nbnd, bndind,  bndptr, higain);
+    else if (ed[higain] > 0 && bndptr[higain] == -1)
+      BNDInsert(nbnd, bndind,  bndptr, higain);
+
+    saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
+    saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+((to+1)%2)*ncon, 1);
+    for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+      k = adjncy[j];
+
+      kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
+      INC_DEC(id[k], ed[k], kwgt);
+
+      if (bndptr[k] != -1 && ed[k] == 0)
+        BNDDelete(nbnd, bndind, bndptr, k);
+      if (bndptr[k] == -1 && ed[k] > 0)
+        BNDInsert(nbnd, bndind, bndptr, k);
+    }
+  }
+
+  if (ctrl->dbglvl&DBG_REFINE) {
+    printf("\tMincut: %6d at %5d, NBND: %6d, NPwgts: [", mincut, mincutorder, nbnd);
+    for (l=0; l<ncon; l++)
+      printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
+    printf("], LB: %.3f\n", Compute2WayHLoadImbalance(ncon, npwgts, tpwgts));
+  }
+
+  graph->mincut = mincut;
+  graph->nbnd = nbnd;
+
+
+  for (i=0; i<ncon; i++) {
+    PQueueFree(ctrl, &parts[i][0]);
+    PQueueFree(ctrl, &parts[i][1]);
+  }
+
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+
+}
+
diff --git a/Metis/mbalance2.c b/Metis/mbalance2.c
new file mode 100644
index 0000000000..717bcef352
--- /dev/null
+++ b/Metis/mbalance2.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * mbalance2.c
+ *
+ * This file contains code that is used to forcefully balance either
+ * bisections or k-sections
+ *
+ * Started 7/29/97
+ * George
+ *
+ * $Id: mbalance2.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function is the entry point of the bisection balancing algorithms.
+**************************************************************************/
+void MocBalance2Way2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec)
+{
+  int i;
+  float tvec[MAXNCON];
+
+  Compute2WayHLoadImbalanceVec(graph->ncon, graph->npwgts, tpwgts, tvec);
+  if (!AreAllBelow(graph->ncon, tvec, ubvec))
+    MocGeneral2WayBalance2(ctrl, graph, tpwgts, ubvec);
+}
+
+
+
+/*************************************************************************
+* This function performs an edge-based FM refinement
+**************************************************************************/
+void MocGeneral2WayBalance2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec)
+{
+  int i, ii, j, k, l, kwgt, nvtxs, ncon, nbnd, nswaps, from, to, pass, me, limit, tmp, cnum;
+  idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind;
+  idxtype *moved, *swaps, *perm, *qnum;
+  float *nvwgt, *npwgts, origbal[MAXNCON], minbal[MAXNCON], newbal[MAXNCON];
+  PQueueType parts[MAXNCON][2];
+  int higain, oldgain, mincut, newcut, mincutorder;
+  float *maxwgt, *minwgt, tvec[MAXNCON];
+
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  xadj = graph->xadj;
+  nvwgt = graph->nvwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+  where = graph->where;
+  id = graph->id;
+  ed = graph->ed;
+  npwgts = graph->npwgts;
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+
+  moved = idxwspacemalloc(ctrl, nvtxs);
+  swaps = idxwspacemalloc(ctrl, nvtxs);
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  qnum = idxwspacemalloc(ctrl, nvtxs);
+
+  limit = amin(amax(0.01*nvtxs, 15), 100);
+
+  /* Setup the weight intervals of the two subdomains */
+  minwgt = fwspacemalloc(ctrl, 2*ncon);
+  maxwgt = fwspacemalloc(ctrl, 2*ncon);
+
+  for (i=0; i<2; i++) {
+    for (j=0; j<ncon; j++) {
+      maxwgt[i*ncon+j] = tpwgts[i]*ubvec[j];
+      minwgt[i*ncon+j] = tpwgts[i]*(1.0/ubvec[j]);
+    }
+  }
+
+
+  /* Initialize the queues */
+  for (i=0; i<ncon; i++) {
+    PQueueInit(ctrl, &parts[i][0], nvtxs, PLUS_GAINSPAN+1);
+    PQueueInit(ctrl, &parts[i][1], nvtxs, PLUS_GAINSPAN+1);
+  }
+  for (i=0; i<nvtxs; i++)
+    qnum[i] = samax(ncon, nvwgt+i*ncon);
+
+  Compute2WayHLoadImbalanceVec(ncon, npwgts, tpwgts, origbal);
+  for (i=0; i<ncon; i++) 
+    minbal[i] = origbal[i];
+
+  newcut = mincut = graph->mincut;
+  mincutorder = -1;
+
+  if (ctrl->dbglvl&DBG_REFINE) {
+    printf("Parts: [");
+    for (l=0; l<ncon; l++)
+      printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
+    printf("] T[%.3f %.3f], Nv-Nb[%5d, %5d]. ICut: %6d, LB: ", tpwgts[0], tpwgts[1], 
+            graph->nvtxs, graph->nbnd, graph->mincut);
+    for (i=0; i<ncon; i++)
+      printf("%.3f ", origbal[i]);
+    printf("[B]\n");
+  }
+
+  idxset(nvtxs, -1, moved);
+
+  ASSERT(ComputeCut(graph, where) == graph->mincut);
+  ASSERT(CheckBnd(graph));
+
+  /* Insert all nodes in the priority queues */
+  nbnd = graph->nbnd;
+  RandomPermute(nvtxs, perm, 1);
+  for (ii=0; ii<nvtxs; ii++) {
+    i = perm[ii];
+    PQueueInsert(&parts[qnum[i]][where[i]], i, ed[i]-id[i]);
+  }
+
+
+  for (nswaps=0; nswaps<nvtxs; nswaps++) {
+    if (AreAllBelow(ncon, minbal, ubvec))
+      break;
+
+    SelectQueue3(ncon, npwgts, tpwgts, &from, &cnum, parts, maxwgt);
+    to = (from+1)%2;
+
+    if (from == -1 || (higain = PQueueGetMax(&parts[cnum][from])) == -1)
+      break;
+
+    saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
+    saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1);
+    newcut -= (ed[higain]-id[higain]);
+    Compute2WayHLoadImbalanceVec(ncon, npwgts, tpwgts, newbal);
+
+    if (IsBetter2wayBalance(ncon, newbal, minbal, ubvec) || 
+        (IsBetter2wayBalance(ncon, newbal, origbal, ubvec) && newcut < mincut)) {
+      mincut = newcut;
+      for (i=0; i<ncon; i++) 
+        minbal[i] = newbal[i];
+      mincutorder = nswaps;
+    }
+    else if (nswaps-mincutorder > limit) { /* We hit the limit, undo last move */
+      newcut += (ed[higain]-id[higain]);
+      saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1);
+      saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
+      break;
+    }
+
+    where[higain] = to;
+    moved[higain] = nswaps;
+    swaps[nswaps] = higain;
+
+    if (ctrl->dbglvl&DBG_MOVEINFO) {
+      printf("Moved %6d from %d(%d). Gain: %5d, Cut: %5d, NPwgts: ", higain, from, cnum, ed[higain]-id[higain], newcut);
+      for (i=0; i<ncon; i++) 
+        printf("(%.3f, %.3f) ", npwgts[i], npwgts[ncon+i]);
+
+      Compute2WayHLoadImbalanceVec(ncon, npwgts, tpwgts, tvec);
+      printf(", LB: ");
+      for (i=0; i<ncon; i++) 
+        printf("%.3f ", tvec[i]);
+      if (mincutorder == nswaps)
+        printf(" *\n");
+      else
+        printf("\n");
+    }
+
+
+    /**************************************************************
+    * Update the id[i]/ed[i] values of the affected nodes
+    ***************************************************************/
+    SWAP(id[higain], ed[higain], tmp);
+    if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) 
+      BNDDelete(nbnd, bndind,  bndptr, higain);
+    if (ed[higain] > 0 && bndptr[higain] == -1)
+      BNDInsert(nbnd, bndind,  bndptr, higain);
+
+    for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+      k = adjncy[j];
+      oldgain = ed[k]-id[k];
+
+      kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
+      INC_DEC(id[k], ed[k], kwgt);
+
+      /* Update the queue position */
+      if (moved[k] == -1)
+        PQueueUpdate(&parts[qnum[k]][where[k]], k, oldgain, ed[k]-id[k]);
+
+      /* Update its boundary information */
+      if (ed[k] == 0 && bndptr[k] != -1) 
+        BNDDelete(nbnd, bndind, bndptr, k);
+      else if (ed[k] > 0 && bndptr[k] == -1)  
+        BNDInsert(nbnd, bndind, bndptr, k);
+    }
+   
+  }
+
+
+
+  /****************************************************************
+  * Roll back computations
+  *****************************************************************/
+  for (i=0; i<nswaps; i++)
+    moved[swaps[i]] = -1;  /* reset moved array */
+  for (nswaps--; nswaps>mincutorder; nswaps--) {
+    higain = swaps[nswaps];
+
+    to = where[higain] = (where[higain]+1)%2;
+    SWAP(id[higain], ed[higain], tmp);
+    if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1])
+      BNDDelete(nbnd, bndind,  bndptr, higain);
+    else if (ed[higain] > 0 && bndptr[higain] == -1)
+      BNDInsert(nbnd, bndind,  bndptr, higain);
+
+    saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
+    saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+((to+1)%2)*ncon, 1);
+    for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+      k = adjncy[j];
+
+      kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
+      INC_DEC(id[k], ed[k], kwgt);
+
+      if (bndptr[k] != -1 && ed[k] == 0)
+        BNDDelete(nbnd, bndind, bndptr, k);
+      if (bndptr[k] == -1 && ed[k] > 0)
+        BNDInsert(nbnd, bndind, bndptr, k);
+    }
+  }
+
+  if (ctrl->dbglvl&DBG_REFINE) {
+    printf("\tMincut: %6d at %5d, NBND: %6d, NPwgts: [", mincut, mincutorder, nbnd);
+    for (i=0; i<ncon; i++)
+      printf("(%.3f, %.3f) ", npwgts[i], npwgts[ncon+i]);
+    printf("], LB: ");
+    Compute2WayHLoadImbalanceVec(ncon, npwgts, tpwgts, tvec);
+    for (i=0; i<ncon; i++) 
+      printf("%.3f ", tvec[i]);
+    printf("\n");
+  }
+
+  graph->mincut = mincut;
+  graph->nbnd = nbnd;
+
+
+  for (i=0; i<ncon; i++) {
+    PQueueFree(ctrl, &parts[i][0]);
+    PQueueFree(ctrl, &parts[i][1]);
+  }
+
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  fwspacefree(ctrl, 2*ncon);
+  fwspacefree(ctrl, 2*ncon);
+
+}
+
+
+
+
+/*************************************************************************
+* This function selects the partition number and the queue from which
+* we will move vertices out
+**************************************************************************/ 
+void SelectQueue3(int ncon, float *npwgts, float *tpwgts, int *from, int *cnum, 
+       PQueueType queues[MAXNCON][2], float *maxwgt)
+{
+  int i, j, maxgain=0;
+  float maxdiff=0.0, diff;
+
+  *from = -1;
+  *cnum = -1;
+
+  /* First determine the side and the queue, irrespective of the presence of nodes */
+  for (j=0; j<2; j++) {
+    for (i=0; i<ncon; i++) {
+      diff = npwgts[j*ncon+i]-maxwgt[j*ncon+i];
+      if (diff >= maxdiff) {
+        maxdiff = diff;
+        *from = j;
+        *cnum = i;
+      }
+    }
+  }
+
+/* DELETE
+j = *from;
+for (i=0; i<ncon; i++)
+  printf("[%5d %5d %.4f %.4f] ", i, PQueueGetSize(&queues[i][j]), npwgts[j*ncon+i], maxwgt[j*ncon+i]);
+printf("***[%5d %5d]\n", *cnum, *from);
+*/
+
+  /* If the desired queue is empty, select a node from that side anyway */
+  if (*from != -1 && PQueueGetSize(&queues[*cnum][*from]) == 0) {
+    for (i=0; i<ncon; i++) {
+      if (PQueueGetSize(&queues[i][*from]) > 0) {
+        maxdiff = (npwgts[(*from)*ncon+i] - maxwgt[(*from)*ncon+i]);
+        *cnum = i;
+        break;
+      }
+    }
+
+    for (i++; i<ncon; i++) {
+      diff = npwgts[(*from)*ncon+i] - maxwgt[(*from)*ncon+i];
+      if (diff > maxdiff && PQueueGetSize(&queues[i][*from]) > 0) {
+        maxdiff = diff;
+        *cnum = i;
+      }
+    }
+  }
+
+  /* If the constraints ar OK, select a high gain vertex */
+  if (*from == -1) {
+    maxgain = -100000;
+    for (j=0; j<2; j++) {
+      for (i=0; i<ncon; i++) {
+        if (PQueueGetSize(&queues[i][j]) > 0 && PQueueGetKey(&queues[i][j]) > maxgain) {
+          maxgain = PQueueGetKey(&queues[i][0]); 
+          *from = j;
+          *cnum = i;
+        }
+      }
+    }
+
+    /* printf("(%2d %2d) %3d\n", *from, *cnum, maxgain); */
+  }
+}
diff --git a/Metis/mcoarsen.c b/Metis/mcoarsen.c
new file mode 100644
index 0000000000..34bd5da46c
--- /dev/null
+++ b/Metis/mcoarsen.c
@@ -0,0 +1,91 @@
+/*
+ * mcoarsen.c
+ *
+ * This file contains the driving routines for the coarsening process 
+ *
+ * Started 7/23/97
+ * George
+ *
+ * $Id: mcoarsen.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function takes a graph and creates a sequence of coarser graphs
+**************************************************************************/
+GraphType *MCCoarsen2Way(CtrlType *ctrl, GraphType *graph)
+{
+  int i, clevel;
+  GraphType *cgraph;
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->CoarsenTmr));
+
+  cgraph = graph;
+
+  clevel = 0;
+  do {
+    if (ctrl->dbglvl&DBG_COARSEN) {
+      printf("%6d %7d %10d [%d] [%6.4f", cgraph->nvtxs, cgraph->nedges, 
+              idxsum(cgraph->nvtxs, cgraph->adjwgtsum), ctrl->CoarsenTo, ctrl->nmaxvwgt);
+      for (i=0; i<graph->ncon; i++)
+        printf(" %5.3f", ssum_strd(cgraph->nvtxs, cgraph->nvwgt+i, cgraph->ncon));
+      printf("]\n");
+    }
+
+    switch (ctrl->CType) {
+      case MATCH_RM:
+        MCMatch_RM(ctrl, cgraph);
+        break;
+      case MATCH_HEM:
+        if (clevel < 1)
+          MCMatch_RM(ctrl, cgraph);
+        else
+          MCMatch_HEM(ctrl, cgraph);
+        break;
+      case MATCH_SHEM:
+        if (clevel < 1)
+          MCMatch_RM(ctrl, cgraph);
+        else
+          MCMatch_SHEM(ctrl, cgraph);
+        break;
+      case MATCH_SHEMKWAY:
+        MCMatch_SHEM(ctrl, cgraph);
+        break;
+      case MATCH_SHEBM_ONENORM:
+        MCMatch_SHEBM(ctrl, cgraph, 1);
+        break;
+      case MATCH_SHEBM_INFNORM:
+        MCMatch_SHEBM(ctrl, cgraph, -1);
+        break;
+      case MATCH_SBHEM_ONENORM:
+        MCMatch_SBHEM(ctrl, cgraph, 1);
+        break;
+      case MATCH_SBHEM_INFNORM:
+        MCMatch_SBHEM(ctrl, cgraph, -1);
+        break;
+      default:
+        errexit("Unknown CType: %d\n", ctrl->CType);
+    }
+
+    cgraph = cgraph->coarser;
+    clevel++;
+
+  } while (cgraph->nvtxs > ctrl->CoarsenTo && cgraph->nvtxs < COARSEN_FRACTION2*cgraph->finer->nvtxs && cgraph->nedges > cgraph->nvtxs/2); 
+
+  if (ctrl->dbglvl&DBG_COARSEN) {
+    printf("%6d %7d %10d [%d] [%6.4f", cgraph->nvtxs, cgraph->nedges, 
+            idxsum(cgraph->nvtxs, cgraph->adjwgtsum), ctrl->CoarsenTo, ctrl->nmaxvwgt);
+    for (i=0; i<graph->ncon; i++)
+      printf(" %5.3f", ssum_strd(cgraph->nvtxs, cgraph->nvwgt+i, cgraph->ncon));
+    printf("]\n");
+  }
+
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->CoarsenTmr));
+
+  return cgraph;
+}
+
diff --git a/Metis/memory.c b/Metis/memory.c
new file mode 100644
index 0000000000..2342de3d91
--- /dev/null
+++ b/Metis/memory.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * memory.c
+ *
+ * This file contains routines that deal with memory allocation
+ *
+ * Started 2/24/96
+ * George
+ *
+ * $Id: memory.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function allocates memory for the workspace
+**************************************************************************/
+void AllocateWorkSpace(CtrlType *ctrl, GraphType *graph, int nparts)
+{
+  ctrl->wspace.pmat = NULL;
+
+  if (ctrl->optype == OP_KMETIS) {
+    ctrl->wspace.edegrees = (EDegreeType *)GKmalloc(graph->nedges*sizeof(EDegreeType), "AllocateWorkSpace: edegrees");
+    ctrl->wspace.vedegrees = NULL;
+    ctrl->wspace.auxcore = (idxtype *)ctrl->wspace.edegrees;
+
+    ctrl->wspace.pmat = idxmalloc(nparts*nparts, "AllocateWorkSpace: pmat");
+
+    /* Memory requirements for different phases
+          Coarsening
+                    Matching: 4*nvtxs vectors
+                 Contraction: 2*nvtxs vectors (from the above 4), 1*nparts, 1*Nedges
+            Total = MAX(4*nvtxs, 2*nvtxs+nparts+nedges)
+
+          Refinement
+                Random Refinement/Balance: 5*nparts + 1*nvtxs + 2*nedges
+                Greedy Refinement/Balance: 5*nparts + 2*nvtxs + 2*nedges + 1*PQueue(==Nvtxs)
+            Total = 5*nparts + 3*nvtxs + 2*nedges
+
+         Total = 5*nparts + 3*nvtxs + 2*nedges 
+    */
+    ctrl->wspace.maxcore = 3*(graph->nvtxs+1) +                 /* Match/Refinement vectors */
+                           5*(nparts+1) +                       /* Partition weights etc */
+                           graph->nvtxs*(sizeof(ListNodeType)/sizeof(idxtype)) + /* Greedy k-way balance/refine */
+                           20  /* padding for 64 bit machines */
+                           ;
+  }
+  else if (ctrl->optype == OP_KVMETIS) {
+    ctrl->wspace.edegrees = NULL;
+    ctrl->wspace.vedegrees = (VEDegreeType *)GKmalloc(graph->nedges*sizeof(VEDegreeType), "AllocateWorkSpace: vedegrees");
+    ctrl->wspace.auxcore = (idxtype *)ctrl->wspace.vedegrees;
+
+    ctrl->wspace.pmat = idxmalloc(nparts*nparts, "AllocateWorkSpace: pmat");
+
+    /* Memory requirements for different phases are identical to KMETIS */
+    ctrl->wspace.maxcore = 3*(graph->nvtxs+1) +                 /* Match/Refinement vectors */
+                           3*(nparts+1) +                       /* Partition weights etc */
+                           graph->nvtxs*(sizeof(ListNodeType)/sizeof(idxtype)) + /* Greedy k-way balance/refine */
+                           20  /* padding for 64 bit machines */
+                           ;
+  }
+  else {
+    ctrl->wspace.edegrees = (EDegreeType *)idxmalloc(graph->nedges, "AllocateWorkSpace: edegrees");
+    ctrl->wspace.vedegrees = NULL;
+    ctrl->wspace.auxcore = (idxtype *)ctrl->wspace.edegrees;
+
+    ctrl->wspace.maxcore = 5*(graph->nvtxs+1) +                 /* Refinement vectors */
+                           4*(nparts+1) +                       /* Partition weights etc */
+                           2*graph->ncon*graph->nvtxs*(sizeof(ListNodeType)/sizeof(idxtype)) + /* 2-way refinement */
+                           2*graph->ncon*(NEG_GAINSPAN+PLUS_GAINSPAN+1)*(sizeof(ListNodeType *)/sizeof(idxtype)) + /* 2-way refinement */
+                           20  /* padding for 64 bit machines */
+                           ;
+  }
+
+  ctrl->wspace.maxcore += HTLENGTH;
+  ctrl->wspace.core = idxmalloc(ctrl->wspace.maxcore, "AllocateWorkSpace: maxcore");
+  ctrl->wspace.ccore = 0;
+}
+
+
+/*************************************************************************
+* This function allocates memory for the workspace
+**************************************************************************/
+void FreeWorkSpace(CtrlType *ctrl, GraphType *graph)
+{
+  GKfree(&ctrl->wspace.edegrees, &ctrl->wspace.vedegrees, &ctrl->wspace.core, &ctrl->wspace.pmat, LTERM);
+}
+
+/*************************************************************************
+* This function returns how may words are left in the workspace
+**************************************************************************/
+int WspaceAvail(CtrlType *ctrl)
+{
+  return ctrl->wspace.maxcore - ctrl->wspace.ccore;
+}
+
+
+/*************************************************************************
+* This function allocate space from the core 
+**************************************************************************/
+idxtype *idxwspacemalloc(CtrlType *ctrl, int n)
+{
+  n += n%2; /* This is a fix for 64 bit machines that require 8-byte pointer allignment */
+
+  ctrl->wspace.ccore += n;
+  ASSERT(ctrl->wspace.ccore <= ctrl->wspace.maxcore);
+  return ctrl->wspace.core + ctrl->wspace.ccore - n;
+}
+
+/*************************************************************************
+* This function frees space from the core 
+**************************************************************************/
+void idxwspacefree(CtrlType *ctrl, int n)
+{
+  n += n%2; /* This is a fix for 64 bit machines that require 8-byte pointer allignment */
+
+  ctrl->wspace.ccore -= n;
+  ASSERT(ctrl->wspace.ccore >= 0);
+}
+
+
+/*************************************************************************
+* This function allocate space from the core 
+**************************************************************************/
+float *fwspacemalloc(CtrlType *ctrl, int n)
+{
+  n += n%2; /* This is a fix for 64 bit machines that require 8-byte pointer allignment */
+
+  ctrl->wspace.ccore += n;
+  ASSERT(ctrl->wspace.ccore <= ctrl->wspace.maxcore);
+  return (float *) (ctrl->wspace.core + ctrl->wspace.ccore - n);
+}
+
+/*************************************************************************
+* This function frees space from the core 
+**************************************************************************/
+void fwspacefree(CtrlType *ctrl, int n)
+{
+  n += n%2; /* This is a fix for 64 bit machines that require 8-byte pointer allignment */
+
+  ctrl->wspace.ccore -= n;
+  ASSERT(ctrl->wspace.ccore >= 0);
+}
+
+
+
+/*************************************************************************
+* This function creates a CoarseGraphType data structure and initializes
+* the various fields
+**************************************************************************/
+GraphType *CreateGraph(void)
+{
+  GraphType *graph;
+
+  graph = (GraphType *)GKmalloc(sizeof(GraphType), "CreateCoarseGraph: graph");
+
+  InitGraph(graph);
+
+  return graph;
+}
+
+
+/*************************************************************************
+* This function creates a CoarseGraphType data structure and initializes
+* the various fields
+**************************************************************************/
+void InitGraph(GraphType *graph) 
+{
+  graph->gdata = graph->rdata = NULL;
+
+  graph->nvtxs = graph->nedges = -1;
+  graph->mincut = graph->minvol = -1;
+
+  graph->xadj = graph->vwgt = graph->adjncy = graph->adjwgt = NULL;
+  graph->adjwgtsum = NULL;
+  graph->label = NULL;
+  graph->cmap = NULL;
+
+  graph->where = graph->pwgts = NULL;
+  graph->id = graph->ed = NULL;
+  graph->bndptr = graph->bndind = NULL;
+  graph->rinfo = NULL;
+  graph->vrinfo = NULL;
+  graph->nrinfo = NULL;
+
+  graph->ncon = -1;
+  graph->nvwgt = NULL;
+  graph->npwgts = NULL;
+
+  graph->vsize = NULL;
+
+  graph->coarser = graph->finer = NULL;
+
+}
+
+/*************************************************************************
+* This function deallocates any memory stored in a graph
+**************************************************************************/
+void FreeGraph(GraphType *graph) 
+{
+
+  GKfree(&graph->gdata, &graph->nvwgt, &graph->rdata, &graph->npwgts, LTERM);
+  free(graph);
+}
+
diff --git a/Metis/mesh.c b/Metis/mesh.c
new file mode 100644
index 0000000000..015f693fed
--- /dev/null
+++ b/Metis/mesh.c
@@ -0,0 +1,398 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * mesh.c
+ *
+ * This file contains routines for converting 3D and 4D finite element
+ * meshes into dual or nodal graphs
+ *
+ * Started 8/18/97
+ * George
+ *
+ * $Id: mesh.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+/*****************************************************************************
+* This function creates a graph corresponding to the dual of a finite element
+* mesh. At this point the supported elements are triangles, tetrahedrons, and
+* bricks.
+******************************************************************************/
+void METIS_MeshToDual(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, 
+                      idxtype *dxadj, idxtype *dadjncy)
+{
+  int esizes[] = {-1, 3, 4, 8, 4};
+
+  if (*numflag == 1)
+    ChangeMesh2CNumbering((*ne)*esizes[*etype], elmnts);
+
+  GENDUALMETIS(*ne, *nn, *etype, elmnts, dxadj, dadjncy);
+
+  if (*numflag == 1)
+    ChangeMesh2FNumbering((*ne)*esizes[*etype], elmnts, *ne, dxadj, dadjncy);
+}
+
+
+/*****************************************************************************
+* This function creates a graph corresponding to the finite element mesh. 
+* At this point the supported elements are triangles, tetrahedrons.
+******************************************************************************/
+void METIS_MeshToNodal(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, 
+                       idxtype *dxadj, idxtype *dadjncy)
+{
+  int esizes[] = {-1, 3, 4, 8, 4};
+
+  if (*numflag == 1)
+    ChangeMesh2CNumbering((*ne)*esizes[*etype], elmnts);
+
+  switch (*etype) {
+    case 1:
+      TRINODALMETIS(*ne, *nn, elmnts, dxadj, dadjncy);
+      break;
+    case 2:
+      TETNODALMETIS(*ne, *nn, elmnts, dxadj, dadjncy);
+      break;
+    case 3:
+      HEXNODALMETIS(*ne, *nn, elmnts, dxadj, dadjncy);
+      break;
+    case 4:
+      QUADNODALMETIS(*ne, *nn, elmnts, dxadj, dadjncy);
+      break;
+  }
+
+  if (*numflag == 1)
+    ChangeMesh2FNumbering((*ne)*esizes[*etype], elmnts, *nn, dxadj, dadjncy);
+}
+
+
+
+/*****************************************************************************
+* This function creates the dual of a finite element mesh
+******************************************************************************/
+void GENDUALMETIS(int nelmnts, int nvtxs, int etype, idxtype *elmnts, idxtype *dxadj, idxtype *dadjncy)
+{
+   int i, j, jj, k, kk, kkk, l, m, n, nedges, mask;
+   idxtype *nptr, *nind;
+   idxtype *mark, ind[200], wgt[200];
+   int esize, esizes[] = {-1, 3, 4, 8, 4},
+       mgcnum, mgcnums[] = {-1, 2, 3, 4, 2};
+
+   mask = (1<<11)-1;
+   mark = idxsmalloc(mask+1, -1, "GENDUALMETIS: mark");
+
+   /* Get the element size and magic number for the particular element */
+   esize = esizes[etype];
+   mgcnum = mgcnums[etype];
+
+   /* Construct the node-element list first */
+   nptr = idxsmalloc(nvtxs+1, 0, "GENDUALMETIS: nptr");
+   for (j=esize*nelmnts, i=0; i<j; i++) 
+     nptr[elmnts[i]]++;
+   MAKECSR(i, nvtxs, nptr);
+
+   nind = idxmalloc(nptr[nvtxs], "GENDUALMETIS: nind");
+   for (k=i=0; i<nelmnts; i++) {
+     for (j=0; j<esize; j++, k++) 
+       nind[nptr[elmnts[k]]++] = i;
+   }
+   for (i=nvtxs; i>0; i--)
+     nptr[i] = nptr[i-1];
+   nptr[0] = 0;
+
+   for (i=0; i<nelmnts; i++) 
+     dxadj[i] = esize*i;
+
+   for (i=0; i<nelmnts; i++) {
+     for (m=j=0; j<esize; j++) {
+       n = elmnts[esize*i+j];
+       for (k=nptr[n+1]-1; k>=nptr[n]; k--) {
+         if ((kk = nind[k]) <= i)
+           break;
+
+         kkk = kk&mask;
+         if ((l = mark[kkk]) == -1) {
+           ind[m] = kk;
+           wgt[m] = 1;
+           mark[kkk] = m++;
+         }
+         else if (ind[l] == kk) {
+           wgt[l]++;
+         }
+         else {
+           for (jj=0; jj<m; jj++) {
+             if (ind[jj] == kk) {
+               wgt[jj]++;
+               break;
+             }
+           }
+           if (jj == m) {
+             ind[m] = kk;
+             wgt[m++] = 1;
+           }
+         }
+       }
+     }
+     for (j=0; j<m; j++) {
+       if (wgt[j] == mgcnum) {
+         k = ind[j];
+         dadjncy[dxadj[i]++] = k;
+         dadjncy[dxadj[k]++] = i;
+       }
+       mark[ind[j]&mask] = -1;
+     }
+   }
+
+   /* Go and consolidate the dxadj and dadjncy */
+   for (j=i=0; i<nelmnts; i++) {
+     for (k=esize*i; k<dxadj[i]; k++, j++)
+       dadjncy[j] = dadjncy[k];
+     dxadj[i] = j;
+   }
+   for (i=nelmnts; i>0; i--)
+     dxadj[i] = dxadj[i-1];
+   dxadj[0] = 0;
+
+   free(mark);
+   free(nptr);
+   free(nind);
+
+}
+
+
+
+
+/*****************************************************************************
+* This function creates the nodal graph of a finite element mesh
+******************************************************************************/
+void TRINODALMETIS(int nelmnts, int nvtxs, idxtype *elmnts, idxtype *dxadj, idxtype *dadjncy)
+{
+   int i, j, jj, k, kk, kkk, l, m, n, nedges;
+   idxtype *nptr, *nind;
+   idxtype *mark;
+
+   /* Construct the node-element list first */
+   nptr = idxsmalloc(nvtxs+1, 0, "TRINODALMETIS: nptr");
+   for (j=3*nelmnts, i=0; i<j; i++) 
+     nptr[elmnts[i]]++;
+   MAKECSR(i, nvtxs, nptr);
+
+   nind = idxmalloc(nptr[nvtxs], "TRINODALMETIS: nind");
+   for (k=i=0; i<nelmnts; i++) {
+     for (j=0; j<3; j++, k++) 
+       nind[nptr[elmnts[k]]++] = i;
+   }
+   for (i=nvtxs; i>0; i--)
+     nptr[i] = nptr[i-1];
+   nptr[0] = 0;
+
+
+   mark = idxsmalloc(nvtxs, -1, "TRINODALMETIS: mark");
+
+   nedges = dxadj[0] = 0;
+   for (i=0; i<nvtxs; i++) {
+     mark[i] = i;
+     for (j=nptr[i]; j<nptr[i+1]; j++) {
+       for (jj=3*nind[j], k=0; k<3; k++, jj++) {
+         kk = elmnts[jj];
+         if (mark[kk] != i) {
+           mark[kk] = i;
+           dadjncy[nedges++] = kk;
+         }
+       }
+     }
+     dxadj[i+1] = nedges;
+   }
+
+   free(mark);
+   free(nptr);
+   free(nind);
+
+}
+
+
+/*****************************************************************************
+* This function creates the nodal graph of a finite element mesh
+******************************************************************************/
+void TETNODALMETIS(int nelmnts, int nvtxs, idxtype *elmnts, idxtype *dxadj, idxtype *dadjncy)
+{
+   int i, j, jj, k, kk, kkk, l, m, n, nedges;
+   idxtype *nptr, *nind;
+   idxtype *mark;
+
+   /* Construct the node-element list first */
+   nptr = idxsmalloc(nvtxs+1, 0, "TETNODALMETIS: nptr");
+   for (j=4*nelmnts, i=0; i<j; i++) 
+     nptr[elmnts[i]]++;
+   MAKECSR(i, nvtxs, nptr);
+
+   nind = idxmalloc(nptr[nvtxs], "TETNODALMETIS: nind");
+   for (k=i=0; i<nelmnts; i++) {
+     for (j=0; j<4; j++, k++) 
+       nind[nptr[elmnts[k]]++] = i;
+   }
+   for (i=nvtxs; i>0; i--)
+     nptr[i] = nptr[i-1];
+   nptr[0] = 0;
+
+
+   mark = idxsmalloc(nvtxs, -1, "TETNODALMETIS: mark");
+
+   nedges = dxadj[0] = 0;
+   for (i=0; i<nvtxs; i++) {
+     mark[i] = i;
+     for (j=nptr[i]; j<nptr[i+1]; j++) {
+       for (jj=4*nind[j], k=0; k<4; k++, jj++) {
+         kk = elmnts[jj];
+         if (mark[kk] != i) {
+           mark[kk] = i;
+           dadjncy[nedges++] = kk;
+         }
+       }
+     }
+     dxadj[i+1] = nedges;
+   }
+
+   free(mark);
+   free(nptr);
+   free(nind);
+
+}
+
+
+/*****************************************************************************
+* This function creates the nodal graph of a finite element mesh
+******************************************************************************/
+void HEXNODALMETIS(int nelmnts, int nvtxs, idxtype *elmnts, idxtype *dxadj, idxtype *dadjncy)
+{
+   int i, j, jj, k, kk, kkk, l, m, n, nedges;
+   idxtype *nptr, *nind;
+   idxtype *mark;
+   int table[8][3] = {1, 3, 4,
+                      0, 2, 5,
+                      1, 3, 6,
+                      0, 2, 7,
+                      0, 5, 7,
+                      1, 4, 6,
+                      2, 5, 7,
+                      3, 4, 6};
+
+   /* Construct the node-element list first */
+   nptr = idxsmalloc(nvtxs+1, 0, "HEXNODALMETIS: nptr");
+   for (j=8*nelmnts, i=0; i<j; i++) 
+     nptr[elmnts[i]]++;
+   MAKECSR(i, nvtxs, nptr);
+
+   nind = idxmalloc(nptr[nvtxs], "HEXNODALMETIS: nind");
+   for (k=i=0; i<nelmnts; i++) {
+     for (j=0; j<8; j++, k++) 
+       nind[nptr[elmnts[k]]++] = i;
+   }
+   for (i=nvtxs; i>0; i--)
+     nptr[i] = nptr[i-1];
+   nptr[0] = 0;
+
+
+   mark = idxsmalloc(nvtxs, -1, "HEXNODALMETIS: mark");
+
+   nedges = dxadj[0] = 0;
+   for (i=0; i<nvtxs; i++) {
+     mark[i] = i;
+     for (j=nptr[i]; j<nptr[i+1]; j++) {
+       jj=8*nind[j];
+       for (k=0; k<8; k++) {
+         if (elmnts[jj+k] == i)
+           break;
+       }
+       ASSERT(k != 8);
+
+       /* You found the index, now go and put the 3 neighbors */
+       kk = elmnts[jj+table[k][0]];
+       if (mark[kk] != i) {
+         mark[kk] = i;
+         dadjncy[nedges++] = kk;
+       }
+       kk = elmnts[jj+table[k][1]];
+       if (mark[kk] != i) {
+         mark[kk] = i;
+         dadjncy[nedges++] = kk;
+       }
+       kk = elmnts[jj+table[k][2]];
+       if (mark[kk] != i) {
+         mark[kk] = i;
+         dadjncy[nedges++] = kk;
+       }
+     }
+     dxadj[i+1] = nedges;
+   }
+
+   free(mark);
+   free(nptr);
+   free(nind);
+
+}
+
+
+/*****************************************************************************
+* This function creates the nodal graph of a finite element mesh
+******************************************************************************/
+void QUADNODALMETIS(int nelmnts, int nvtxs, idxtype *elmnts, idxtype *dxadj, idxtype *dadjncy)
+{
+   int i, j, jj, k, kk, kkk, l, m, n, nedges;
+   idxtype *nptr, *nind;
+   idxtype *mark;
+   int table[4][2] = {1, 3, 
+                      0, 2,
+                      1, 3, 
+                      0, 2}; 
+
+   /* Construct the node-element list first */
+   nptr = idxsmalloc(nvtxs+1, 0, "QUADNODALMETIS: nptr");
+   for (j=4*nelmnts, i=0; i<j; i++) 
+     nptr[elmnts[i]]++;
+   MAKECSR(i, nvtxs, nptr);
+
+   nind = idxmalloc(nptr[nvtxs], "QUADNODALMETIS: nind");
+   for (k=i=0; i<nelmnts; i++) {
+     for (j=0; j<4; j++, k++) 
+       nind[nptr[elmnts[k]]++] = i;
+   }
+   for (i=nvtxs; i>0; i--)
+     nptr[i] = nptr[i-1];
+   nptr[0] = 0;
+
+
+   mark = idxsmalloc(nvtxs, -1, "QUADNODALMETIS: mark");
+
+   nedges = dxadj[0] = 0;
+   for (i=0; i<nvtxs; i++) {
+     mark[i] = i;
+     for (j=nptr[i]; j<nptr[i+1]; j++) {
+       jj=4*nind[j];
+       for (k=0; k<4; k++) {
+         if (elmnts[jj+k] == i)
+           break;
+       }
+       ASSERT(k != 4);
+
+       /* You found the index, now go and put the 2 neighbors */
+       kk = elmnts[jj+table[k][0]];
+       if (mark[kk] != i) {
+         mark[kk] = i;
+         dadjncy[nedges++] = kk;
+       }
+       kk = elmnts[jj+table[k][1]];
+       if (mark[kk] != i) {
+         mark[kk] = i;
+         dadjncy[nedges++] = kk;
+       }
+     }
+     dxadj[i+1] = nedges;
+   }
+
+   free(mark);
+   free(nptr);
+   free(nind);
+
+}
diff --git a/Metis/meshpart.c b/Metis/meshpart.c
new file mode 100644
index 0000000000..e010fe3a80
--- /dev/null
+++ b/Metis/meshpart.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * meshpart.c
+ *
+ * This file contains routines for partitioning finite element meshes.
+ *
+ * Started 9/29/97
+ * George
+ *
+ * $Id: meshpart.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function partitions a finite element mesh by partitioning its nodal
+* graph using KMETIS and then assigning elements in a load balanced fashion.
+**************************************************************************/
+void METIS_PartMeshNodal(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, 
+                         int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
+{
+  int i, j, k, me;
+  idxtype *xadj, *adjncy, *pwgts;
+  int options[10], pnumflag=0, wgtflag=0;
+  int nnbrs, nbrind[200], nbrwgt[200], maxpwgt;
+  int esize, esizes[] = {-1, 3, 4, 8, 4};
+
+  esize = esizes[*etype];
+
+  if (*numflag == 1)
+    ChangeMesh2CNumbering((*ne)*esize, elmnts);
+
+  xadj = idxmalloc(*nn+1, "METIS_MESHPARTNODAL: xadj");
+  adjncy = idxmalloc(20*(*nn), "METIS_MESHPARTNODAL: adjncy");
+
+  METIS_MeshToNodal(ne, nn, elmnts, etype, &pnumflag, xadj, adjncy);
+
+  adjncy = realloc(adjncy, xadj[*nn]*sizeof(idxtype));
+
+  options[0] = 0;
+  METIS_PartGraphKway(nn, xadj, adjncy, NULL, NULL, &wgtflag, &pnumflag, nparts, options, edgecut, npart);
+
+  /* OK, now compute an element partition based on the nodal partition npart */
+  idxset(*ne, -1, epart);
+  pwgts = idxsmalloc(*nparts, 0, "METIS_MESHPARTNODAL: pwgts");
+  for (i=0; i<*ne; i++) {
+    me = npart[elmnts[i*esize]];
+    for (j=1; j<esize; j++) {
+      if (npart[elmnts[i*esize+j]] != me)
+        break;
+    }
+    if (j == esize) {
+      epart[i] = me;
+      pwgts[me]++;
+    }
+  }
+
+  maxpwgt = 1.03*(*ne)/(*nparts);
+  for (i=0; i<*ne; i++) {
+    if (epart[i] == -1) { /* Assign the boundary element */
+      nnbrs = 0;
+      for (j=0; j<esize; j++) {
+        me = npart[elmnts[i*esize+j]];
+        for (k=0; k<nnbrs; k++) {
+          if (nbrind[k] == me) {
+            nbrwgt[k]++;
+            break;
+          }
+        }
+        if (k == nnbrs) {
+          nbrind[nnbrs] = me;
+          nbrwgt[nnbrs++] = 1;
+        }
+      }
+      /* Try to assign it first to the domain with most things in common */
+      j = iamax(nnbrs, nbrwgt);
+      if (pwgts[nbrind[j]] < maxpwgt) {
+        epart[i] = nbrind[j];
+      }
+      else {
+        /* If that fails, assign it to a light domain */
+        for (j=0; j<nnbrs; j++) {
+          if (pwgts[nbrind[j]] < maxpwgt) {
+            epart[i] = nbrind[j];
+            break;
+          }
+        }
+        if (j == nnbrs) 
+          epart[i] = nbrind[iamax(nnbrs, nbrwgt)];
+      }
+      pwgts[epart[i]]++;
+    }
+  }
+
+  if (*numflag == 1)
+    ChangeMesh2FNumbering2((*ne)*esize, elmnts, *ne, *nn, epart, npart);
+
+  GKfree(&xadj, &adjncy, &pwgts, LTERM);
+
+}
+
+
+/*************************************************************************
+* This function partitions a finite element mesh by partitioning its dual
+* graph using KMETIS and then assigning nodes in a load balanced fashion.
+**************************************************************************/
+void METIS_PartMeshDual(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, 
+                        int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
+{
+  int i, j, k, me;
+  idxtype *xadj, *adjncy, *pwgts, *nptr, *nind;
+  int options[10], pnumflag=0, wgtflag=0;
+  int nnbrs, nbrind[200], nbrwgt[200], maxpwgt;
+  int esize, esizes[] = {-1, 3, 4, 8, 4};
+
+  esize = esizes[*etype];
+
+  if (*numflag == 1)
+    ChangeMesh2CNumbering((*ne)*esize, elmnts);
+
+  xadj = idxmalloc(*ne+1, "METIS_MESHPARTNODAL: xadj");
+  adjncy = idxmalloc(esize*(*ne), "METIS_MESHPARTNODAL: adjncy");
+
+  METIS_MeshToDual(ne, nn, elmnts, etype, &pnumflag, xadj, adjncy);
+
+  options[0] = 0;
+  METIS_PartGraphKway(ne, xadj, adjncy, NULL, NULL, &wgtflag, &pnumflag, nparts, options, edgecut, epart);
+
+  /* Construct the node-element list */
+  nptr = idxsmalloc(*nn+1, 0, "METIS_MESHPARTDUAL: nptr");
+  for (j=esize*(*ne), i=0; i<j; i++) 
+    nptr[elmnts[i]]++;
+  MAKECSR(i, *nn, nptr);
+
+  nind = idxmalloc(nptr[*nn], "METIS_MESHPARTDUAL: nind");
+  for (k=i=0; i<(*ne); i++) {
+    for (j=0; j<esize; j++, k++) 
+      nind[nptr[elmnts[k]]++] = i;
+  }
+  for (i=(*nn); i>0; i--)
+    nptr[i] = nptr[i-1];
+  nptr[0] = 0;
+
+
+  /* OK, now compute a nodal partition based on the element partition npart */
+  idxset(*nn, -1, npart);
+  pwgts = idxsmalloc(*nparts, 0, "METIS_MESHPARTDUAL: pwgts");
+  for (i=0; i<*nn; i++) {
+    me = epart[nind[nptr[i]]];
+    for (j=nptr[i]+1; j<nptr[i+1]; j++) {
+      if (epart[nind[j]] != me)
+        break;
+    }
+    if (j == nptr[i+1]) {
+      npart[i] = me;
+      pwgts[me]++;
+    }
+  }
+
+  maxpwgt = 1.03*(*nn)/(*nparts);
+  for (i=0; i<*nn; i++) {
+    if (npart[i] == -1) { /* Assign the boundary element */
+      nnbrs = 0;
+      for (j=nptr[i]; j<nptr[i+1]; j++) {
+        me = epart[nind[j]];
+        for (k=0; k<nnbrs; k++) {
+          if (nbrind[k] == me) {
+            nbrwgt[k]++;
+            break;
+          }
+        }
+        if (k == nnbrs) {
+          nbrind[nnbrs] = me;
+          nbrwgt[nnbrs++] = 1;
+        }
+      }
+      /* Try to assign it first to the domain with most things in common */
+      j = iamax(nnbrs, nbrwgt);
+      if (pwgts[nbrind[j]] < maxpwgt) {
+        npart[i] = nbrind[j];
+      }
+      else {
+        /* If that fails, assign it to a light domain */
+        npart[i] = nbrind[0];
+        for (j=0; j<nnbrs; j++) {
+          if (pwgts[nbrind[j]] < maxpwgt) {
+            npart[i] = nbrind[j];
+            break;
+          }
+        }
+      }
+      pwgts[npart[i]]++;
+    }
+  }
+
+  if (*numflag == 1)
+    ChangeMesh2FNumbering2((*ne)*esize, elmnts, *ne, *nn, epart, npart);
+
+  GKfree(&xadj, &adjncy, &pwgts, &nptr, &nind, LTERM);
+
+}
diff --git a/Metis/metis.h b/Metis/metis.h
new file mode 100644
index 0000000000..13c0b9cd2a
--- /dev/null
+++ b/Metis/metis.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * metis.h
+ *
+ * This file includes all necessary header files
+ *
+ * Started 8/27/94
+ * George
+ *
+ * $Id: metis.h,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ */
+
+
+#include <stdio.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#else
+#include <malloc.h>
+#endif
+#include <strings.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+#include <stdarg.h>
+#include <time.h>
+
+#ifdef DMALLOC
+#include <dmalloc.h>
+#endif
+
+#include <defs.h>
+#include <struct.h>
+#include <macros.h>
+#include <rename.h>
+#include <proto.h>
+
diff --git a/Metis/mfm.c b/Metis/mfm.c
new file mode 100644
index 0000000000..820278f799
--- /dev/null
+++ b/Metis/mfm.c
@@ -0,0 +1,344 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * mfm.c
+ *
+ * This file contains code that implements the edge-based FM refinement
+ *
+ * Started 7/23/97
+ * George
+ *
+ * $Id: mfm.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function performs an edge-based FM refinement
+**************************************************************************/
+void MocFM_2WayEdgeRefine(CtrlType *ctrl, GraphType *graph, float *tpwgts, int npasses)
+{
+  int i, ii, j, k, l, kwgt, nvtxs, ncon, nbnd, nswaps, from, to, pass, me, limit, tmp, cnum;
+  idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind;
+  idxtype *moved, *swaps, *perm, *qnum;
+  float *nvwgt, *npwgts, mindiff[MAXNCON], origbal, minbal, newbal;
+  PQueueType parts[MAXNCON][2];
+  int higain, oldgain, mincut, initcut, newcut, mincutorder;
+  float rtpwgts[2];
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  xadj = graph->xadj;
+  nvwgt = graph->nvwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+  where = graph->where;
+  id = graph->id;
+  ed = graph->ed;
+  npwgts = graph->npwgts;
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+
+  moved = idxwspacemalloc(ctrl, nvtxs);
+  swaps = idxwspacemalloc(ctrl, nvtxs);
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  qnum = idxwspacemalloc(ctrl, nvtxs);
+
+  limit = amin(amax(0.01*nvtxs, 25), 150);
+
+  /* Initialize the queues */
+  for (i=0; i<ncon; i++) {
+    PQueueInit(ctrl, &parts[i][0], nvtxs, PLUS_GAINSPAN+1);
+    PQueueInit(ctrl, &parts[i][1], nvtxs, PLUS_GAINSPAN+1);
+  }
+  for (i=0; i<nvtxs; i++)
+    qnum[i] = samax(ncon, nvwgt+i*ncon);
+
+  origbal = Compute2WayHLoadImbalance(ncon, npwgts, tpwgts);
+
+  rtpwgts[0] = origbal*tpwgts[0];
+  rtpwgts[1] = origbal*tpwgts[1];
+
+
+  if (ctrl->dbglvl&DBG_REFINE) {
+    printf("Parts: [");
+    for (l=0; l<ncon; l++)
+      printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
+    printf("] T[%.3f %.3f], Nv-Nb[%5d, %5d]. ICut: %6d, LB: %.3f\n", tpwgts[0], tpwgts[1], graph->nvtxs, graph->nbnd, graph->mincut, origbal);
+  }
+
+  idxset(nvtxs, -1, moved);
+  for (pass=0; pass<npasses; pass++) { /* Do a number of passes */
+    for (i=0; i<ncon; i++) { 
+      PQueueReset(&parts[i][0]);
+      PQueueReset(&parts[i][1]);
+    }
+
+    mincutorder = -1;
+    newcut = mincut = initcut = graph->mincut;
+    for (i=0; i<ncon; i++)
+      mindiff[i] = fabs(tpwgts[0]-npwgts[i]);
+    minbal = Compute2WayHLoadImbalance(ncon, npwgts, tpwgts);
+
+    ASSERT(ComputeCut(graph, where) == graph->mincut);
+    ASSERT(CheckBnd(graph));
+
+    /* Insert boundary nodes in the priority queues */
+    nbnd = graph->nbnd;
+    RandomPermute(nbnd, perm, 1);
+    for (ii=0; ii<nbnd; ii++) {
+      i = bndind[perm[ii]];
+      ASSERT(ed[i] > 0 || id[i] == 0);
+      ASSERT(bndptr[i] != -1);
+      PQueueInsert(&parts[qnum[i]][where[i]], i, ed[i]-id[i]);
+    }
+
+    for (nswaps=0; nswaps<nvtxs; nswaps++) {
+      SelectQueue(ncon, npwgts, rtpwgts, &from, &cnum, parts);
+      to = (from+1)%2;
+
+      if (from == -1 || (higain = PQueueGetMax(&parts[cnum][from])) == -1)
+        break;
+      ASSERT(bndptr[higain] != -1);
+
+      saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
+      saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1);
+
+      newcut -= (ed[higain]-id[higain]);
+      newbal = Compute2WayHLoadImbalance(ncon, npwgts, tpwgts);
+
+      if ((newcut < mincut && newbal-origbal <= .00001) || 
+          (newcut == mincut && (newbal < minbal || 
+                                (newbal == minbal && BetterBalance(ncon, npwgts, tpwgts, mindiff))))) {
+        mincut = newcut;
+        minbal = newbal;
+        mincutorder = nswaps;
+        for (i=0; i<ncon; i++)
+          mindiff[i] = fabs(tpwgts[0]-npwgts[i]);
+      }
+      else if (nswaps-mincutorder > limit) { /* We hit the limit, undo last move */
+        newcut += (ed[higain]-id[higain]);
+        saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1);
+        saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
+        break;
+      }
+
+      where[higain] = to;
+      moved[higain] = nswaps;
+      swaps[nswaps] = higain;
+
+      if (ctrl->dbglvl&DBG_MOVEINFO) {
+        printf("Moved %6d from %d(%d). Gain: %5d, Cut: %5d, NPwgts: ", higain, from, cnum, ed[higain]-id[higain], newcut);
+        for (l=0; l<ncon; l++) 
+          printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
+        printf(", %.3f LB: %.3f\n", minbal, newbal);
+      }
+
+
+      /**************************************************************
+      * Update the id[i]/ed[i] values of the affected nodes
+      ***************************************************************/
+      SWAP(id[higain], ed[higain], tmp);
+      if (ed[higain] == 0 && xadj[higain] < xadj[higain+1]) 
+        BNDDelete(nbnd, bndind,  bndptr, higain);
+
+      for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+        k = adjncy[j];
+        oldgain = ed[k]-id[k];
+
+        kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
+        INC_DEC(id[k], ed[k], kwgt);
+
+        /* Update its boundary information and queue position */
+        if (bndptr[k] != -1) { /* If k was a boundary vertex */
+          if (ed[k] == 0) { /* Not a boundary vertex any more */
+            BNDDelete(nbnd, bndind, bndptr, k);
+            if (moved[k] == -1)  /* Remove it if in the queues */
+              PQueueDelete(&parts[qnum[k]][where[k]], k, oldgain);
+          }
+          else { /* If it has not been moved, update its position in the queue */
+            if (moved[k] == -1)
+              PQueueUpdate(&parts[qnum[k]][where[k]], k, oldgain, ed[k]-id[k]);
+          }
+        }
+        else {
+          if (ed[k] > 0) {  /* It will now become a boundary vertex */
+            BNDInsert(nbnd, bndind, bndptr, k);
+            if (moved[k] == -1) 
+              PQueueInsert(&parts[qnum[k]][where[k]], k, ed[k]-id[k]);
+          }
+        }
+      }
+
+    }
+
+
+    /****************************************************************
+    * Roll back computations
+    *****************************************************************/
+    for (i=0; i<nswaps; i++)
+      moved[swaps[i]] = -1;  /* reset moved array */
+    for (nswaps--; nswaps>mincutorder; nswaps--) {
+      higain = swaps[nswaps];
+
+      to = where[higain] = (where[higain]+1)%2;
+      SWAP(id[higain], ed[higain], tmp);
+      if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1])
+        BNDDelete(nbnd, bndind,  bndptr, higain);
+      else if (ed[higain] > 0 && bndptr[higain] == -1)
+        BNDInsert(nbnd, bndind,  bndptr, higain);
+
+      saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
+      saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+((to+1)%2)*ncon, 1);
+      for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+        k = adjncy[j];
+
+        kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
+        INC_DEC(id[k], ed[k], kwgt);
+
+        if (bndptr[k] != -1 && ed[k] == 0)
+          BNDDelete(nbnd, bndind, bndptr, k);
+        if (bndptr[k] == -1 && ed[k] > 0)
+          BNDInsert(nbnd, bndind, bndptr, k);
+      }
+    }
+
+    if (ctrl->dbglvl&DBG_REFINE) {
+      printf("\tMincut: %6d at %5d, NBND: %6d, NPwgts: [", mincut, mincutorder, nbnd);
+      for (l=0; l<ncon; l++)
+        printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
+      printf("], LB: %.3f\n", Compute2WayHLoadImbalance(ncon, npwgts, tpwgts));
+    }
+
+    graph->mincut = mincut;
+    graph->nbnd = nbnd;
+
+    if (mincutorder == -1 || mincut == initcut)
+      break;
+  }
+
+  for (i=0; i<ncon; i++) {
+    PQueueFree(ctrl, &parts[i][0]);
+    PQueueFree(ctrl, &parts[i][1]);
+  }
+
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+
+}
+
+
+/*************************************************************************
+* This function selects the partition number and the queue from which
+* we will move vertices out
+**************************************************************************/ 
+void SelectQueue(int ncon, float *npwgts, float *tpwgts, int *from, int *cnum, PQueueType queues[MAXNCON][2])
+{
+  int i, part, maxgain=0;
+  float max, maxdiff=0.0;
+
+  *from = -1;
+  *cnum = -1;
+
+  /* First determine the side and the queue, irrespective of the presence of nodes */
+  for (part=0; part<2; part++) {
+    for (i=0; i<ncon; i++) {
+      if (npwgts[part*ncon+i]-tpwgts[part] >= maxdiff) {
+        maxdiff = npwgts[part*ncon+i]-tpwgts[part];
+        *from = part;
+        *cnum = i;
+      }
+    }
+  }
+
+  /* printf("Selected1 %d(%d) -> %d [%5f]\n", *from, *cnum, PQueueGetSize(&queues[*cnum][*from]), maxdiff); */
+
+  if (*from != -1 && PQueueGetSize(&queues[*cnum][*from]) == 0) {
+    /* The desired queue is empty, select a node from that side anyway */
+    for (i=0; i<ncon; i++) {
+      if (PQueueGetSize(&queues[i][*from]) > 0) {
+        max = npwgts[(*from)*ncon + i];
+        *cnum = i;
+        break;
+      }
+    }
+
+    for (i++; i<ncon; i++) {
+      if (npwgts[(*from)*ncon + i] > max && PQueueGetSize(&queues[i][*from]) > 0) {
+        max = npwgts[(*from)*ncon + i];
+        *cnum = i;
+      }
+    }
+  }
+
+  /* Check to see if you can focus on the cut */
+  if (maxdiff <= 0.0 || *from == -1) {
+    maxgain = -100000;
+
+    for (part=0; part<2; part++) {
+      for (i=0; i<ncon; i++) {
+        if (PQueueGetSize(&queues[i][part]) > 0 && PQueueGetKey(&queues[i][part]) > maxgain) {
+          maxgain = PQueueGetKey(&queues[i][part]); 
+          *from = part;
+          *cnum = i;
+        }
+      }
+    }
+  }
+
+  /* printf("Selected2 %d(%d) -> %d\n", *from, *cnum, PQueueGetSize(&queues[*cnum][*from])); */
+}
+
+
+
+
+
+/*************************************************************************
+* This function checks if the balance achieved is better than the diff 
+* For now, it uses a 2-norm measure
+**************************************************************************/ 
+int BetterBalance(int ncon, float *npwgts, float *tpwgts, float *diff)
+{
+  int i;
+  float ndiff[MAXNCON];
+
+  for (i=0; i<ncon; i++)
+    ndiff[i] = fabs(tpwgts[0]-npwgts[i]);
+   
+  return snorm2(ncon, ndiff) < snorm2(ncon, diff);
+}
+
+
+
+/*************************************************************************
+* This function computes the load imbalance over all the constrains
+**************************************************************************/ 
+float Compute2WayHLoadImbalance(int ncon, float *npwgts, float *tpwgts)
+{
+  int i;
+  float max=0.0, temp;
+
+  for (i=0; i<ncon; i++) {
+    /* temp = amax(npwgts[i]/tpwgts[0], npwgts[ncon+i]/tpwgts[1]); */
+    temp = fabs(tpwgts[0]-npwgts[i])/tpwgts[0];
+    max = (max < temp ? temp : max);
+  }
+  return 1.0+max;
+}
+
+
+/*************************************************************************
+* This function computes the load imbalance over all the constrains
+* For now assume that we just want balanced partitionings
+**************************************************************************/ 
+void Compute2WayHLoadImbalanceVec(int ncon, float *npwgts, float *tpwgts, float *lbvec)
+{
+  int i;
+
+  for (i=0; i<ncon; i++) 
+    lbvec[i] = 1.0 + fabs(tpwgts[0]-npwgts[i])/tpwgts[0];
+}
+
diff --git a/Metis/mfm2.c b/Metis/mfm2.c
new file mode 100644
index 0000000000..0b2a4d5211
--- /dev/null
+++ b/Metis/mfm2.c
@@ -0,0 +1,349 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * mfm2.c
+ *
+ * This file contains code that implements the edge-based FM refinement
+ *
+ * Started 7/23/97
+ * George
+ *
+ * $Id: mfm2.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function performs an edge-based FM refinement
+**************************************************************************/
+void MocFM_2WayEdgeRefine2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *orgubvec, 
+       int npasses)
+{
+  int i, ii, j, k, l, kwgt, nvtxs, ncon, nbnd, nswaps, from, to, pass, me, limit, tmp, cnum;
+  idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind;
+  idxtype *moved, *swaps, *perm, *qnum;
+  float *nvwgt, *npwgts, origdiff[MAXNCON], origbal[MAXNCON], minbal[MAXNCON];
+  PQueueType parts[MAXNCON][2];
+  int higain, oldgain, mincut, initcut, newcut, mincutorder;
+  float *maxwgt, *minwgt, ubvec[MAXNCON], tvec[MAXNCON];
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  xadj = graph->xadj;
+  nvwgt = graph->nvwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+  where = graph->where;
+  id = graph->id;
+  ed = graph->ed;
+  npwgts = graph->npwgts;
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+
+  moved = idxwspacemalloc(ctrl, nvtxs);
+  swaps = idxwspacemalloc(ctrl, nvtxs);
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  qnum = idxwspacemalloc(ctrl, nvtxs);
+
+  limit = amin(amax(0.01*nvtxs, 15), 100);
+
+  Compute2WayHLoadImbalanceVec(ncon, npwgts, tpwgts, origbal);
+  for (i=0; i<ncon; i++) {
+    origdiff[i] = fabs(tpwgts[0]-npwgts[i]);
+    ubvec[i] = amax(origbal[i], orgubvec[i]);
+  }
+
+  /* Setup the weight intervals of the two subdomains */
+  minwgt = fwspacemalloc(ctrl, 2*ncon);
+  maxwgt = fwspacemalloc(ctrl, 2*ncon);
+
+  for (i=0; i<2; i++) {
+    for (j=0; j<ncon; j++) {
+      maxwgt[i*ncon+j] = tpwgts[i]*ubvec[j];
+      minwgt[i*ncon+j] = tpwgts[i]*(1.0/ubvec[j]);
+    }
+  }
+
+  /* Initialize the queues */
+  for (i=0; i<ncon; i++) {
+    PQueueInit(ctrl, &parts[i][0], nvtxs, PLUS_GAINSPAN+1);
+    PQueueInit(ctrl, &parts[i][1], nvtxs, PLUS_GAINSPAN+1);
+  }
+  for (i=0; i<nvtxs; i++)
+    qnum[i] = samax(ncon, nvwgt+i*ncon);
+
+
+  if (ctrl->dbglvl&DBG_REFINE) {
+    printf("Parts: [");
+    for (l=0; l<ncon; l++)
+      printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
+    printf("] T[%.3f %.3f], Nv-Nb[%5d, %5d]. ICut: %6d, LB: ", tpwgts[0], tpwgts[1], 
+            graph->nvtxs, graph->nbnd, graph->mincut);
+    for (i=0; i<ncon; i++)
+      printf("%.3f ", origbal[i]);
+    printf("\n");
+  }
+
+  idxset(nvtxs, -1, moved);
+  for (pass=0; pass<npasses; pass++) { /* Do a number of passes */
+    for (i=0; i<ncon; i++) { 
+      PQueueReset(&parts[i][0]);
+      PQueueReset(&parts[i][1]);
+    }
+
+    mincutorder = -1;
+    newcut = mincut = initcut = graph->mincut;
+    Compute2WayHLoadImbalanceVec(ncon, npwgts, tpwgts, minbal);
+
+    ASSERT(ComputeCut(graph, where) == graph->mincut);
+    ASSERT(CheckBnd(graph));
+
+    /* Insert boundary nodes in the priority queues */
+    nbnd = graph->nbnd;
+    RandomPermute(nbnd, perm, 1);
+    for (ii=0; ii<nbnd; ii++) {
+      i = bndind[perm[ii]];
+      ASSERT(ed[i] > 0 || id[i] == 0);
+      ASSERT(bndptr[i] != -1);
+      PQueueInsert(&parts[qnum[i]][where[i]], i, ed[i]-id[i]);
+    }
+
+    for (nswaps=0; nswaps<nvtxs; nswaps++) {
+      SelectQueue2(ncon, npwgts, tpwgts, &from, &cnum, parts, maxwgt);
+      to = (from+1)%2;
+
+      if (from == -1 || (higain = PQueueGetMax(&parts[cnum][from])) == -1)
+        break;
+      ASSERT(bndptr[higain] != -1);
+
+      newcut -= (ed[higain]-id[higain]);
+      saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
+      saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1);
+
+      Compute2WayHLoadImbalanceVec(ncon, npwgts, tpwgts, tvec);
+      if ((newcut < mincut && AreAllBelow(ncon, tvec, ubvec)) ||
+          (newcut == mincut && IsBetter2wayBalance(ncon, tvec, minbal, ubvec))) {
+        mincut = newcut;
+        for (i=0; i<ncon; i++) 
+          minbal[i] = tvec[i];
+        mincutorder = nswaps;
+      }
+      else if (nswaps-mincutorder > limit) { /* We hit the limit, undo last move */
+        newcut += (ed[higain]-id[higain]);
+        saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1);
+        saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
+        break;
+      }
+
+      where[higain] = to;
+      moved[higain] = nswaps;
+      swaps[nswaps] = higain;
+
+      if (ctrl->dbglvl&DBG_MOVEINFO) {
+        printf("Moved %6d from %d(%d). Gain: %5d, Cut: %5d, NPwgts: ", higain, from, cnum, ed[higain]-id[higain], newcut);
+        for (l=0; l<ncon; l++) 
+          printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
+
+        printf(", LB: ");
+        for (i=0; i<ncon; i++) 
+          printf("%.3f ", tvec[i]);
+        if (mincutorder == nswaps)
+          printf(" *\n");
+        else
+          printf("\n");
+      }
+
+
+      /**************************************************************
+      * Update the id[i]/ed[i] values of the affected nodes
+      ***************************************************************/
+      SWAP(id[higain], ed[higain], tmp);
+      if (ed[higain] == 0 && xadj[higain] < xadj[higain+1]) 
+        BNDDelete(nbnd, bndind,  bndptr, higain);
+
+      for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+        k = adjncy[j];
+        oldgain = ed[k]-id[k];
+
+        kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
+        INC_DEC(id[k], ed[k], kwgt);
+
+        /* Update its boundary information and queue position */
+        if (bndptr[k] != -1) { /* If k was a boundary vertex */
+          if (ed[k] == 0) { /* Not a boundary vertex any more */
+            BNDDelete(nbnd, bndind, bndptr, k);
+            if (moved[k] == -1)  /* Remove it if in the queues */
+              PQueueDelete(&parts[qnum[k]][where[k]], k, oldgain);
+          }
+          else { /* If it has not been moved, update its position in the queue */
+            if (moved[k] == -1)
+              PQueueUpdate(&parts[qnum[k]][where[k]], k, oldgain, ed[k]-id[k]);
+          }
+        }
+        else {
+          if (ed[k] > 0) {  /* It will now become a boundary vertex */
+            BNDInsert(nbnd, bndind, bndptr, k);
+            if (moved[k] == -1) 
+              PQueueInsert(&parts[qnum[k]][where[k]], k, ed[k]-id[k]);
+          }
+        }
+      }
+
+    }
+
+
+    /****************************************************************
+    * Roll back computations
+    *****************************************************************/
+    for (i=0; i<nswaps; i++)
+      moved[swaps[i]] = -1;  /* reset moved array */
+    for (nswaps--; nswaps>mincutorder; nswaps--) {
+      higain = swaps[nswaps];
+
+      to = where[higain] = (where[higain]+1)%2;
+      SWAP(id[higain], ed[higain], tmp);
+      if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1])
+        BNDDelete(nbnd, bndind,  bndptr, higain);
+      else if (ed[higain] > 0 && bndptr[higain] == -1)
+        BNDInsert(nbnd, bndind,  bndptr, higain);
+
+      saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
+      saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+((to+1)%2)*ncon, 1);
+      for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+        k = adjncy[j];
+
+        kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
+        INC_DEC(id[k], ed[k], kwgt);
+
+        if (bndptr[k] != -1 && ed[k] == 0)
+          BNDDelete(nbnd, bndind, bndptr, k);
+        if (bndptr[k] == -1 && ed[k] > 0)
+          BNDInsert(nbnd, bndind, bndptr, k);
+      }
+    }
+
+    if (ctrl->dbglvl&DBG_REFINE) {
+      printf("\tMincut: %6d at %5d, NBND: %6d, NPwgts: [", mincut, mincutorder, nbnd);
+      for (l=0; l<ncon; l++)
+        printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
+      printf("], LB: ");
+      Compute2WayHLoadImbalanceVec(ncon, npwgts, tpwgts, tvec);
+      for (i=0; i<ncon; i++) 
+        printf("%.3f ", tvec[i]);
+      printf("\n");
+    }
+
+    graph->mincut = mincut;
+    graph->nbnd = nbnd;
+
+    if (mincutorder == -1 || mincut == initcut)
+      break;
+  }
+
+  for (i=0; i<ncon; i++) {
+    PQueueFree(ctrl, &parts[i][0]);
+    PQueueFree(ctrl, &parts[i][1]);
+  }
+
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  fwspacefree(ctrl, 2*ncon);
+  fwspacefree(ctrl, 2*ncon);
+
+}
+
+
+/*************************************************************************
+* This function selects the partition number and the queue from which
+* we will move vertices out
+**************************************************************************/ 
+void SelectQueue2(int ncon, float *npwgts, float *tpwgts, int *from, int *cnum, 
+       PQueueType queues[MAXNCON][2], float *maxwgt)
+{
+  int i, j, maxgain=0;
+  float diff, max, maxdiff=0.0;
+
+  *from = -1;
+  *cnum = -1;
+
+  /* First determine the side and the queue, irrespective of the presence of nodes */
+  for (j=0; j<2; j++) {
+    for (i=0; i<ncon; i++) {
+      diff = npwgts[j*ncon+i]-maxwgt[j*ncon+i];
+      if (diff >= maxdiff) {
+        maxdiff = diff;
+        *from = j;
+        *cnum = i;
+      }
+    }
+  }
+
+  if (*from != -1 && PQueueGetSize(&queues[*cnum][*from]) == 0) {
+    /* The desired queue is empty, select a node from that side anyway */
+    for (i=0; i<ncon; i++) {
+      if (PQueueGetSize(&queues[i][*from]) > 0) {
+        max = (npwgts[(*from)*ncon+i] - maxwgt[(*from)*ncon+i]);
+        *cnum = i;
+        break;
+      }
+    }
+
+    for (i++; i<ncon; i++) {
+      diff = npwgts[(*from)*ncon+i] - maxwgt[(*from)*ncon+i];
+      if (diff > max && PQueueGetSize(&queues[i][*from]) > 0) {
+        max = diff;
+        *cnum = i;
+      }
+    }
+  }
+
+  /* Check to see if you can focus on the cut */
+  if (maxdiff <= 0.0 || *from == -1) {
+    maxgain = -100000;
+
+    for (j=0; j<2; j++) {
+      for (i=0; i<ncon; i++) {
+        if (PQueueGetSize(&queues[i][j]) > 0 && PQueueGetKey(&queues[i][j]) > maxgain) {
+          maxgain = PQueueGetKey(&queues[i][j]); 
+          *from = j;
+          *cnum = i;
+        }
+      }
+    }
+
+    /* printf("(%2d %2d) %3d\n", *from, *cnum, maxgain); */
+  }
+}
+
+
+/*************************************************************************
+* This function checks if the newbal is better than oldbal given the
+* ubvector ubvec
+**************************************************************************/
+int IsBetter2wayBalance(int ncon, float *newbal, float *oldbal, float *ubvec)
+{
+  int i, j;
+  float max1=0.0, max2=0.0, sum1=0.0, sum2=0.0, tmp;
+
+  for (i=0; i<ncon; i++) {
+    tmp = (newbal[i]-1)/(ubvec[i]-1);
+    max1 = (max1 < tmp ? tmp : max1);
+    sum1 += tmp;
+
+    tmp = (oldbal[i]-1)/(ubvec[i]-1);
+    max2 = (max2 < tmp ? tmp : max2);
+    sum2 += tmp;
+  }
+
+  if (max1 < max2)
+    return 1;
+  else if (max1 > max2)
+    return 0;
+  else
+    return sum1 <= sum2;
+}
+
+
diff --git a/Metis/mincover.c b/Metis/mincover.c
new file mode 100644
index 0000000000..3ebd4091c7
--- /dev/null
+++ b/Metis/mincover.c
@@ -0,0 +1,259 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * mincover.c
+ *
+ * This file implements the minimum cover algorithm
+ *
+ * Started 8/1/97
+ * George
+ *
+ * $Id: mincover.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ */
+
+#include <metis.h>
+
+/*************************************************************************
+* Constants used by mincover algorithm
+**************************************************************************/
+#define INCOL 10
+#define INROW 20
+#define VC 1
+#define SC 2
+#define HC 3
+#define VR 4
+#define SR 5
+#define HR 6
+
+
+/*************************************************************************
+* This function returns the min-cover of a bipartite graph.
+* The algorithm used is due to Hopcroft and Karp as modified by Duff etal
+* adj: the adjacency list of the bipartite graph
+*       asize: the number of vertices in the first part of the bipartite graph
+* bsize-asize: the number of vertices in the second part
+*        0..(asize-1) > A vertices
+*        asize..bsize > B vertices
+*
+* Returns:
+*  cover : the actual cover (array)
+*  csize : the size of the cover
+**************************************************************************/
+void MinCover(idxtype *xadj, idxtype *adjncy, int asize, int bsize, idxtype *cover, int *csize)
+{
+  int i, j;
+  idxtype *mate, *queue, *flag, *level, *lst;
+  int fptr, rptr, lstptr;
+  int row, maxlevel, col;
+
+  mate = idxsmalloc(bsize, -1, "MinCover: mate");
+  flag = idxmalloc(bsize, "MinCover: flag");
+  level = idxmalloc(bsize, "MinCover: level");
+  queue = idxmalloc(bsize, "MinCover: queue");
+  lst = idxmalloc(bsize, "MinCover: lst");
+
+  /* Get a cheap matching */
+  for (i=0; i<asize; i++) {
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      if (mate[adjncy[j]] == -1) {
+        mate[i] = adjncy[j];
+        mate[adjncy[j]] = i;
+        break;
+      }
+    }
+  }
+
+  /* Get into the main loop */
+  while (1) {
+    /* Initialization */
+    fptr = rptr = 0;   /* Empty Queue */
+    lstptr = 0;        /* Empty List */
+    for (i=0; i<bsize; i++) {
+      level[i] = -1;
+      flag[i] = 0;
+    }
+    maxlevel = bsize;
+
+    /* Insert free nodes into the queue */
+    for (i=0; i<asize; i++) 
+      if (mate[i] == -1) {
+        queue[rptr++] = i;
+        level[i] = 0;
+      }
+
+    /* Perform the BFS */
+    while (fptr != rptr) {
+      row = queue[fptr++];
+      if (level[row] < maxlevel) {
+        flag[row] = 1;
+        for (j=xadj[row]; j<xadj[row+1]; j++) {
+          col = adjncy[j];
+          if (!flag[col]) {  /* If this column has not been accessed yet */
+            flag[col] = 1;
+            if (mate[col] == -1) { /* Free column node was found */
+              maxlevel = level[row];
+              lst[lstptr++] = col;
+            }
+            else { /* This column node is matched */
+              if (flag[mate[col]]) 
+                printf("\nSomething wrong, flag[%d] is 1",mate[col]);
+              queue[rptr++] = mate[col];
+              level[mate[col]] = level[row] + 1;
+            }
+          }
+        }
+      } 
+    }
+
+    if (lstptr == 0)
+      break;   /* No free columns can be reached */
+
+    /* Perform restricted DFS from the free column nodes */
+    for (i=0; i<lstptr; i++)
+      MinCover_Augment(xadj, adjncy, lst[i], mate, flag, level, maxlevel);
+  }
+
+  MinCover_Decompose(xadj, adjncy, asize, bsize, mate, cover, csize);
+
+  GKfree(&mate, &flag, &level, &queue, &lst, LTERM);
+
+}
+
+
+/*************************************************************************
+* This function perfoms a restricted DFS and augments matchings
+**************************************************************************/
+int MinCover_Augment(idxtype *xadj, idxtype *adjncy, int col, idxtype *mate, idxtype *flag, idxtype *level, int maxlevel)
+{
+  int i;
+  int row = -1;
+  int status;
+
+  flag[col] = 2;
+  for (i=xadj[col]; i<xadj[col+1]; i++) {
+    row = adjncy[i];
+
+    if (flag[row] == 1) { /* First time through this row node */
+      if (level[row] == maxlevel) {  /* (col, row) is an edge of the G^T */
+        flag[row] = 2;  /* Mark this node as being visited */
+        if (maxlevel != 0)
+          status = MinCover_Augment(xadj, adjncy, mate[row], mate, flag, level, maxlevel-1);
+        else
+          status = 1;
+
+        if (status) {
+          mate[col] = row;
+          mate[row] = col;
+          return 1;
+        }
+      }
+    }
+  }
+
+  return 0;
+}
+
+
+
+/*************************************************************************
+* This function performs a coarse decomposition and determines the 
+* min-cover.
+* REF: Pothen ACMTrans. on Amth Software
+**************************************************************************/
+void MinCover_Decompose(idxtype *xadj, idxtype *adjncy, int asize, int bsize, idxtype *mate, idxtype *cover, int *csize)
+{
+  int i, k;
+  idxtype *where;
+  int card[10];
+
+  where = idxmalloc(bsize, "MinCover_Decompose: where");
+  for (i=0; i<10; i++)
+    card[i] = 0;
+
+  for (i=0; i<asize; i++)
+    where[i] = SC;
+  for (; i<bsize; i++)
+    where[i] = SR;
+
+  for (i=0; i<asize; i++) 
+    if (mate[i] == -1)  
+      MinCover_ColDFS(xadj, adjncy, i, mate, where, INCOL);
+  for (; i<bsize; i++) 
+    if (mate[i] == -1)  
+      MinCover_RowDFS(xadj, adjncy, i, mate, where, INROW);
+
+  for (i=0; i<bsize; i++) 
+    card[where[i]]++;
+
+  k = 0;
+  if (abs(card[VC]+card[SC]-card[HR]) < abs(card[VC]-card[SR]-card[HR])) {  /* S = VC+SC+HR */
+    /* printf("%d %d ",vc+sc, hr); */
+    for (i=0; i<bsize; i++) 
+      if (where[i] == VC || where[i] == SC || where[i] == HR)
+        cover[k++] = i;
+  }
+  else {  /* S = VC+SR+HR */
+    /* printf("%d %d ",vc, hr+sr); */
+    for (i=0; i<bsize; i++) 
+      if (where[i] == VC || where[i] == SR || where[i] == HR)
+        cover[k++] = i;
+  }
+
+  *csize = k;
+  free(where);
+
+}
+
+
+/*************************************************************************
+* This function perfoms a dfs starting from an unmatched col node
+* forming alternate paths
+**************************************************************************/
+void MinCover_ColDFS(idxtype *xadj, idxtype *adjncy, int root, idxtype *mate, idxtype *where, int flag)
+{
+  int i;
+
+  if (flag == INCOL) {
+    if (where[root] == HC)
+      return;
+    where[root] = HC;
+    for (i=xadj[root]; i<xadj[root+1]; i++) 
+      MinCover_ColDFS(xadj, adjncy, adjncy[i], mate, where, INROW);
+  }
+  else {
+    if (where[root] == HR)
+      return;
+    where[root] = HR;
+    if (mate[root] != -1)
+      MinCover_ColDFS(xadj, adjncy, mate[root], mate, where, INCOL);
+  }
+
+}
+
+/*************************************************************************
+* This function perfoms a dfs starting from an unmatched col node
+* forming alternate paths
+**************************************************************************/
+void MinCover_RowDFS(idxtype *xadj, idxtype *adjncy, int root, idxtype *mate, idxtype *where, int flag)
+{
+  int i;
+
+  if (flag == INROW) {
+    if (where[root] == VR)
+      return;
+    where[root] = VR;
+    for (i=xadj[root]; i<xadj[root+1]; i++) 
+      MinCover_RowDFS(xadj, adjncy, adjncy[i], mate, where, INCOL);
+  }
+  else {
+    if (where[root] == VC)
+      return;
+    where[root] = VC;
+    if (mate[root] != -1)
+      MinCover_RowDFS(xadj, adjncy, mate[root], mate, where, INROW);
+  }
+
+}
+
+
+
diff --git a/Metis/minitpart.c b/Metis/minitpart.c
new file mode 100644
index 0000000000..2f77d221a9
--- /dev/null
+++ b/Metis/minitpart.c
@@ -0,0 +1,355 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * minitpart.c
+ *
+ * This file contains code that performs the initial partition of the
+ * coarsest graph
+ *
+ * Started 7/23/97
+ * George
+ *
+ * $Id: minitpart.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+/*************************************************************************
+* This function computes the initial bisection of the coarsest graph
+**************************************************************************/
+void MocInit2WayPartition(CtrlType *ctrl, GraphType *graph, float *tpwgts, float ubfactor) 
+{
+  int i, dbglvl;
+
+  dbglvl = ctrl->dbglvl;
+  IFSET(ctrl->dbglvl, DBG_REFINE, ctrl->dbglvl -= DBG_REFINE);
+  IFSET(ctrl->dbglvl, DBG_MOVEINFO, ctrl->dbglvl -= DBG_MOVEINFO);
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr));
+
+  switch (ctrl->IType) {
+    case IPART_GGPKL:
+      MocGrowBisection(ctrl, graph, tpwgts, ubfactor);
+      break;
+    case IPART_RANDOM:
+      MocRandomBisection(ctrl, graph, tpwgts, ubfactor);
+      break;
+    default:
+      errexit("Unknown initial partition type: %d\n", ctrl->IType);
+  }
+
+  IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial Cut: %d [%d]\n", graph->mincut, graph->where[0]));
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr));
+  ctrl->dbglvl = dbglvl;
+
+}
+
+
+
+
+
+/*************************************************************************
+* This function takes a graph and produces a bisection by using a region
+* growing algorithm. The resulting partition is returned in
+* graph->where
+**************************************************************************/
+void MocGrowBisection(CtrlType *ctrl, GraphType *graph, float *tpwgts, float ubfactor)
+{
+  int i, j, k, nvtxs, ncon, from, bestcut, mincut, nbfs;
+  idxtype *bestwhere, *where;
+
+  nvtxs = graph->nvtxs;
+
+  MocAllocate2WayPartitionMemory(ctrl, graph);
+  where = graph->where;
+
+  bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere");
+  nbfs = 2*(nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS);
+  bestcut = idxsum(graph->nedges, graph->adjwgt);  
+
+  for (; nbfs>0; nbfs--) {
+    idxset(nvtxs, 1, where);
+    where[RandomInRange(nvtxs)] = 0;
+
+    MocCompute2WayPartitionParams(ctrl, graph);
+
+    MocInit2WayBalance(ctrl, graph, tpwgts);
+
+    MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 4); 
+
+    MocBalance2Way(ctrl, graph, tpwgts, 1.02);
+    MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 4); 
+
+    if (bestcut >= graph->mincut) {
+      bestcut = graph->mincut;
+      idxcopy(nvtxs, where, bestwhere);
+      if (bestcut == 0)
+        break;
+    }
+  }
+
+  graph->mincut = bestcut;
+  idxcopy(nvtxs, bestwhere, where);
+
+  GKfree(&bestwhere, LTERM);
+}
+
+
+
+/*************************************************************************
+* This function takes a graph and produces a bisection by using a region
+* growing algorithm. The resulting partition is returned in
+* graph->where
+**************************************************************************/
+void MocRandomBisection(CtrlType *ctrl, GraphType *graph, float *tpwgts, float ubfactor)
+{
+  int i, ii, j, k, nvtxs, ncon, from, bestcut, mincut, nbfs, qnum;
+  idxtype *bestwhere, *where, *perm;
+  int counts[MAXNCON];
+  float *nvwgt;
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  nvwgt = graph->nvwgt;
+
+  MocAllocate2WayPartitionMemory(ctrl, graph);
+  where = graph->where;
+
+  bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere");
+  nbfs = 2*(nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS);
+  bestcut = idxsum(graph->nedges, graph->adjwgt);  
+  perm = idxmalloc(nvtxs, "BisectGraph: perm");
+
+  for (; nbfs>0; nbfs--) {
+    for (i=0; i<ncon; i++)
+      counts[i] = 0;
+
+    RandomPermute(nvtxs, perm, 1);
+
+    /* Partition by spliting the queues randomly */
+    for (ii=0; ii<nvtxs; ii++) {
+      i = perm[ii];
+      qnum = samax(ncon, nvwgt+i*ncon);
+      where[i] = counts[qnum];
+      counts[qnum] = (counts[qnum]+1)%2;
+    }
+
+    MocCompute2WayPartitionParams(ctrl, graph);
+
+    MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 6); 
+    MocBalance2Way(ctrl, graph, tpwgts, 1.02);
+    MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 6); 
+    MocBalance2Way(ctrl, graph, tpwgts, 1.02);
+    MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 6); 
+
+    /*
+    printf("Edgecut: %6d, NPwgts: [", graph->mincut);
+    for (i=0; i<graph->ncon; i++)
+      printf("(%.3f %.3f) ", graph->npwgts[i], graph->npwgts[graph->ncon+i]);
+    printf("]\n");
+    */
+
+    if (bestcut >= graph->mincut) {
+      bestcut = graph->mincut;
+      idxcopy(nvtxs, where, bestwhere);
+      if (bestcut == 0)
+        break;
+    }
+  }
+
+  graph->mincut = bestcut;
+  idxcopy(nvtxs, bestwhere, where);
+
+  GKfree(&bestwhere, &perm, LTERM);
+}
+
+
+
+
+/*************************************************************************
+* This function balances two partitions by moving the highest gain 
+* (including negative gain) vertices to the other domain.
+* It is used only when tha unbalance is due to non contigous
+* subdomains. That is, the are no boundary vertices.
+* It moves vertices from the domain that is overweight to the one that 
+* is underweight.
+**************************************************************************/
+void MocInit2WayBalance(CtrlType *ctrl, GraphType *graph, float *tpwgts)
+{
+  int i, ii, j, k, l, kwgt, nvtxs, nbnd, ncon, nswaps, from, to, pass, me, cnum, tmp;
+  idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind;
+  idxtype *perm, *qnum;
+  float *nvwgt, *npwgts;
+  PQueueType parts[MAXNCON][2];
+  int higain, oldgain, mincut;
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  nvwgt = graph->nvwgt;
+  adjwgt = graph->adjwgt;
+  where = graph->where;
+  id = graph->id;
+  ed = graph->ed;
+  npwgts = graph->npwgts;
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  qnum = idxwspacemalloc(ctrl, nvtxs);
+
+  /* This is called for initial partitioning so we know from where to pick nodes */
+  from = 1;
+  to = (from+1)%2;
+
+  if (ctrl->dbglvl&DBG_REFINE) {
+    printf("Parts: [");
+    for (l=0; l<ncon; l++)
+      printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
+    printf("] T[%.3f %.3f], Nv-Nb[%5d, %5d]. ICut: %6d, LB: %.3f [B]\n", tpwgts[0], tpwgts[1], 
+           graph->nvtxs, graph->nbnd, graph->mincut, 
+           Compute2WayHLoadImbalance(ncon, npwgts, tpwgts));
+  }
+
+  for (i=0; i<ncon; i++) {
+    PQueueInit(ctrl, &parts[i][0], nvtxs, PLUS_GAINSPAN+1);
+    PQueueInit(ctrl, &parts[i][1], nvtxs, PLUS_GAINSPAN+1);
+  }
+
+  ASSERT(ComputeCut(graph, where) == graph->mincut);
+  ASSERT(CheckBnd(graph));
+  ASSERT(CheckGraph(graph));
+
+  /* Compute the queues in which each vertex will be assigned to */
+  for (i=0; i<nvtxs; i++)
+    qnum[i] = samax(ncon, nvwgt+i*ncon);
+
+  /* Insert the nodes of the proper partition in the appropriate priority queue */
+  RandomPermute(nvtxs, perm, 1);
+  for (ii=0; ii<nvtxs; ii++) {
+    i = perm[ii];
+    if (where[i] == from) {
+      if (ed[i] > 0)
+        PQueueInsert(&parts[qnum[i]][0], i, ed[i]-id[i]);
+      else
+        PQueueInsert(&parts[qnum[i]][1], i, ed[i]-id[i]);
+    }
+  }
+
+
+  mincut = graph->mincut;
+  nbnd = graph->nbnd;
+  for (nswaps=0; nswaps<nvtxs; nswaps++) {
+    if (AreAnyVwgtsBelow(ncon, 1.0, npwgts+from*ncon, 0.0, nvwgt, tpwgts[from]))
+      break;
+
+    if ((cnum = SelectQueueOneWay(ncon, npwgts, tpwgts, from, parts)) == -1)
+      break;
+
+    if ((higain = PQueueGetMax(&parts[cnum][0])) == -1)
+      higain = PQueueGetMax(&parts[cnum][1]);
+
+    mincut -= (ed[higain]-id[higain]);
+    saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
+    saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1);
+
+    where[higain] = to;
+
+    if (ctrl->dbglvl&DBG_MOVEINFO) {
+      printf("Moved %6d from %d(%d). [%5d] %5d, NPwgts: ", higain, from, cnum, ed[higain]-id[higain], mincut);
+      for (l=0; l<ncon; l++) 
+        printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
+      printf(", LB: %.3f\n", Compute2WayHLoadImbalance(ncon, npwgts, tpwgts));
+      if (ed[higain] == 0 && id[higain] > 0)
+        printf("\t Pulled from the interior!\n");
+    }
+
+
+    /**************************************************************
+    * Update the id[i]/ed[i] values of the affected nodes
+    ***************************************************************/
+    SWAP(id[higain], ed[higain], tmp);
+    if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) 
+      BNDDelete(nbnd, bndind,  bndptr, higain);
+    if (ed[higain] > 0 && bndptr[higain] == -1)
+      BNDInsert(nbnd, bndind,  bndptr, higain);
+
+    for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+      k = adjncy[j];
+      oldgain = ed[k]-id[k];
+
+      kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
+      INC_DEC(id[k], ed[k], kwgt);
+
+      /* Update the queue position */
+      if (where[k] == from) {
+        if (ed[k] > 0 && bndptr[k] == -1) {  /* It moves in boundary */
+          PQueueDelete(&parts[qnum[k]][1], k, oldgain);
+          PQueueInsert(&parts[qnum[k]][0], k, ed[k]-id[k]);
+        }
+        else { /* It must be in the boundary already */
+          if (bndptr[k] == -1)
+            printf("What you thought was wrong!\n");
+          PQueueUpdate(&parts[qnum[k]][0], k, oldgain, ed[k]-id[k]);
+        }
+      }
+
+      /* Update its boundary information */
+      if (ed[k] == 0 && bndptr[k] != -1) 
+        BNDDelete(nbnd, bndind, bndptr, k);
+      else if (ed[k] > 0 && bndptr[k] == -1)  
+        BNDInsert(nbnd, bndind, bndptr, k);
+    }
+
+    ASSERTP(ComputeCut(graph, where) == mincut, ("%d != %d\n", ComputeCut(graph, where), mincut));
+
+  }
+
+  if (ctrl->dbglvl&DBG_REFINE) {
+    printf("\tMincut: %6d, NBND: %6d, NPwgts: ", mincut, nbnd);
+    for (l=0; l<ncon; l++)
+      printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
+    printf(", LB: %.3f\n", Compute2WayHLoadImbalance(ncon, npwgts, tpwgts));
+  }
+
+  graph->mincut = mincut;
+  graph->nbnd = nbnd;
+
+  for (i=0; i<ncon; i++) {
+    PQueueFree(ctrl, &parts[i][0]);
+    PQueueFree(ctrl, &parts[i][1]);
+  }
+
+  ASSERT(ComputeCut(graph, where) == graph->mincut);
+  ASSERT(CheckBnd(graph));
+
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+
+
+/*************************************************************************
+* This function selects the partition number and the queue from which
+* we will move vertices out
+**************************************************************************/ 
+int SelectQueueOneWay(int ncon, float *npwgts, float *tpwgts, int from, PQueueType queues[MAXNCON][2])
+{
+  int i, cnum=-1;
+  float max=0.0;
+
+  for (i=0; i<ncon; i++) {
+    if (npwgts[from*ncon+i]-tpwgts[from] >= max && 
+        PQueueGetSize(&queues[i][0]) + PQueueGetSize(&queues[i][1]) > 0) {
+      max = npwgts[from*ncon+i]-tpwgts[0];
+      cnum = i;
+    }
+  }
+
+  return cnum;
+}
+
+
diff --git a/Metis/minitpart2.c b/Metis/minitpart2.c
new file mode 100644
index 0000000000..efda6fbdf2
--- /dev/null
+++ b/Metis/minitpart2.c
@@ -0,0 +1,368 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * minitpart2.c
+ *
+ * This file contains code that performs the initial partition of the
+ * coarsest graph
+ *
+ * Started 7/23/97
+ * George
+ *
+ * $Id: minitpart2.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+/*************************************************************************
+* This function computes the initial bisection of the coarsest graph
+**************************************************************************/
+void MocInit2WayPartition2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec) 
+{
+  int dbglvl;
+
+  dbglvl = ctrl->dbglvl;
+  IFSET(ctrl->dbglvl, DBG_REFINE, ctrl->dbglvl -= DBG_REFINE);
+  IFSET(ctrl->dbglvl, DBG_MOVEINFO, ctrl->dbglvl -= DBG_MOVEINFO);
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr));
+
+  switch (ctrl->IType) {
+    case IPART_GGPKL:
+    case IPART_RANDOM:
+      MocGrowBisection2(ctrl, graph, tpwgts, ubvec);
+      break;
+    case 3:
+      MocGrowBisectionNew2(ctrl, graph, tpwgts, ubvec);
+      break;
+    default:
+      errexit("Unknown initial partition type: %d\n", ctrl->IType);
+  }
+
+  IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial Cut: %d\n", graph->mincut));
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr));
+  ctrl->dbglvl = dbglvl;
+
+}
+
+
+
+
+/*************************************************************************
+* This function takes a graph and produces a bisection by using a region
+* growing algorithm. The resulting partition is returned in
+* graph->where
+**************************************************************************/
+void MocGrowBisection2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec)
+{
+  int i, j, k, nvtxs, ncon, from, bestcut, mincut, nbfs;
+  idxtype *bestwhere, *where;
+
+  nvtxs = graph->nvtxs;
+
+  MocAllocate2WayPartitionMemory(ctrl, graph);
+  where = graph->where;
+
+  bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere");
+  nbfs = 2*(nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS);
+  bestcut = idxsum(graph->nedges, graph->adjwgt);  
+
+  for (; nbfs>0; nbfs--) {
+    idxset(nvtxs, 1, where);
+    where[RandomInRange(nvtxs)] = 0;
+
+    MocCompute2WayPartitionParams(ctrl, graph);
+
+    MocBalance2Way2(ctrl, graph, tpwgts, ubvec);
+
+    MocFM_2WayEdgeRefine2(ctrl, graph, tpwgts, ubvec, 4); 
+
+    MocBalance2Way2(ctrl, graph, tpwgts, ubvec);
+    MocFM_2WayEdgeRefine2(ctrl, graph, tpwgts, ubvec, 4); 
+
+    if (bestcut > graph->mincut) {
+      bestcut = graph->mincut;
+      idxcopy(nvtxs, where, bestwhere);
+      if (bestcut == 0)
+        break;
+    }
+  }
+
+  graph->mincut = bestcut;
+  idxcopy(nvtxs, bestwhere, where);
+
+  GKfree(&bestwhere, LTERM);
+}
+
+
+
+
+
+
+/*************************************************************************
+* This function takes a graph and produces a bisection by using a region
+* growing algorithm. The resulting partition is returned in
+* graph->where
+**************************************************************************/
+void MocGrowBisectionNew2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec)
+{
+  int i, j, k, nvtxs, ncon, from, bestcut, mincut, nbfs;
+  idxtype *bestwhere, *where;
+
+  nvtxs = graph->nvtxs;
+
+  MocAllocate2WayPartitionMemory(ctrl, graph);
+  where = graph->where;
+
+  bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere");
+  nbfs = 2*(nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS);
+  bestcut = idxsum(graph->nedges, graph->adjwgt);  
+
+  for (; nbfs>0; nbfs--) {
+    idxset(nvtxs, 1, where);
+    where[RandomInRange(nvtxs)] = 0;
+
+    MocCompute2WayPartitionParams(ctrl, graph);
+
+    MocInit2WayBalance2(ctrl, graph, tpwgts, ubvec);
+
+    MocFM_2WayEdgeRefine2(ctrl, graph, tpwgts, ubvec, 4); 
+
+    if (bestcut > graph->mincut) {
+      bestcut = graph->mincut;
+      idxcopy(nvtxs, where, bestwhere);
+      if (bestcut == 0)
+        break;
+    }
+  }
+
+  graph->mincut = bestcut;
+  idxcopy(nvtxs, bestwhere, where);
+
+  GKfree(&bestwhere, LTERM);
+}
+
+
+
+/*************************************************************************
+* This function balances two partitions by moving the highest gain 
+* (including negative gain) vertices to the other domain.
+* It is used only when tha unbalance is due to non contigous
+* subdomains. That is, the are no boundary vertices.
+* It moves vertices from the domain that is overweight to the one that 
+* is underweight.
+**************************************************************************/
+void MocInit2WayBalance2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec)
+{
+  int i, ii, j, k, l, kwgt, nvtxs, nbnd, ncon, nswaps, from, to, pass, me, cnum, tmp, imin;
+  idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind;
+  idxtype *moved, *perm, *qnum;
+  float *nvwgt, *npwgts, minwgt;
+  PQueueType parts[MAXNCON][2];
+  int higain, oldgain, mincut;
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  nvwgt = graph->nvwgt;
+  adjwgt = graph->adjwgt;
+  where = graph->where;
+  id = graph->id;
+  ed = graph->ed;
+  npwgts = graph->npwgts;
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+
+  moved = idxwspacemalloc(ctrl, nvtxs);
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  qnum = idxwspacemalloc(ctrl, nvtxs);
+
+  /* This is called for initial partitioning so we know from where to pick nodes */
+  from = 1;
+  to = (from+1)%2;
+
+  if (ctrl->dbglvl&DBG_REFINE) {
+    printf("Parts: [");
+    for (l=0; l<ncon; l++)
+      printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
+    printf("] T[%.3f %.3f], Nv-Nb[%5d, %5d]. ICut: %6d, LB: %.3f [B]\n", tpwgts[0], tpwgts[1], graph->nvtxs, graph->nbnd, graph->mincut, ComputeLoadImbalance(ncon, 2, npwgts, tpwgts));
+  }
+
+  for (i=0; i<ncon; i++) {
+    PQueueInit(ctrl, &parts[i][0], nvtxs, PLUS_GAINSPAN+1);
+    PQueueInit(ctrl, &parts[i][1], nvtxs, PLUS_GAINSPAN+1);
+  }
+
+  idxset(nvtxs, -1, moved);
+
+  ASSERT(ComputeCut(graph, where) == graph->mincut);
+  ASSERT(CheckBnd(graph));
+  ASSERT(CheckGraph(graph));
+
+  /* Compute the queues in which each vertex will be assigned to */
+  for (i=0; i<nvtxs; i++)
+    qnum[i] = samax(ncon, nvwgt+i*ncon);
+
+  /* Insert the nodes of the proper partition in the appropriate priority queue */
+  RandomPermute(nvtxs, perm, 1);
+  for (ii=0; ii<nvtxs; ii++) {
+    i = perm[ii];
+    if (where[i] == from) {
+      if (ed[i] > 0)
+        PQueueInsert(&parts[qnum[i]][0], i, ed[i]-id[i]);
+      else
+        PQueueInsert(&parts[qnum[i]][1], i, ed[i]-id[i]);
+    }
+  }
+
+/*
+  for (i=0; i<ncon; i++)
+    printf("Queue #%d has %d %d\n", i, parts[i][0].nnodes, parts[i][1].nnodes);
+*/
+
+  /* Determine the termination criterion */
+  imin = 0;
+  for (i=1; i<ncon; i++) 
+    imin = (ubvec[i] < ubvec[imin] ? i : imin);
+  minwgt = .5/ubvec[imin];
+
+  mincut = graph->mincut;
+  nbnd = graph->nbnd;
+  for (nswaps=0; nswaps<nvtxs; nswaps++) {
+    /* Exit as soon as the minimum weight crossed over */
+    if (npwgts[to*ncon+imin] > minwgt)  
+      break;
+
+    if ((cnum = SelectQueueOneWay2(ncon, npwgts+to*ncon, parts, ubvec)) == -1)
+      break;
+
+    if ((higain = PQueueGetMax(&parts[cnum][0])) == -1)
+      higain = PQueueGetMax(&parts[cnum][1]);
+
+    mincut -= (ed[higain]-id[higain]);
+    saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
+    saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1);
+
+    where[higain] = to;
+    moved[higain] = nswaps;
+
+    if (ctrl->dbglvl&DBG_MOVEINFO) {
+      printf("Moved %6d from %d(%d). [%5d] %5d, NPwgts: ", higain, from, cnum, ed[higain]-id[higain], mincut);
+      for (l=0; l<ncon; l++) 
+        printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
+      printf(", LB: %.3f\n", ComputeLoadImbalance(ncon, 2, npwgts, tpwgts));
+      if (ed[higain] == 0 && id[higain] > 0)
+        printf("\t Pulled from the interior!\n");
+    }
+
+
+    /**************************************************************
+    * Update the id[i]/ed[i] values of the affected nodes
+    ***************************************************************/
+    SWAP(id[higain], ed[higain], tmp);
+    if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) 
+      BNDDelete(nbnd, bndind,  bndptr, higain);
+    if (ed[higain] > 0 && bndptr[higain] == -1)
+      BNDInsert(nbnd, bndind,  bndptr, higain);
+
+    for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+      k = adjncy[j];
+      oldgain = ed[k]-id[k];
+
+      kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
+      INC_DEC(id[k], ed[k], kwgt);
+
+      /* Update the queue position */
+      if (moved[k] == -1 && where[k] == from) {
+        if (ed[k] > 0 && bndptr[k] == -1) {  /* It moves in boundary */
+          PQueueDelete(&parts[qnum[k]][1], k, oldgain);
+          PQueueInsert(&parts[qnum[k]][0], k, ed[k]-id[k]);
+        }
+        else { /* It must be in the boundary already */
+          if (bndptr[k] == -1)
+            printf("What you thought was wrong!\n");
+          PQueueUpdate(&parts[qnum[k]][0], k, oldgain, ed[k]-id[k]);
+        }
+      }
+
+      /* Update its boundary information */
+      if (ed[k] == 0 && bndptr[k] != -1) 
+        BNDDelete(nbnd, bndind, bndptr, k);
+      else if (ed[k] > 0 && bndptr[k] == -1)  
+        BNDInsert(nbnd, bndind, bndptr, k);
+    }
+
+    ASSERTP(ComputeCut(graph, where) == mincut, ("%d != %d\n", ComputeCut(graph, where), mincut));
+
+  }
+
+  if (ctrl->dbglvl&DBG_REFINE) {
+    printf("\tMincut: %6d, NBND: %6d, NPwgts: ", mincut, nbnd);
+    for (l=0; l<ncon; l++)
+      printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
+    printf(", LB: %.3f\n", ComputeLoadImbalance(ncon, 2, npwgts, tpwgts));
+  }
+
+  graph->mincut = mincut;
+  graph->nbnd = nbnd;
+
+  for (i=0; i<ncon; i++) {
+    PQueueFree(ctrl, &parts[i][0]);
+    PQueueFree(ctrl, &parts[i][1]);
+  }
+
+  ASSERT(ComputeCut(graph, where) == graph->mincut);
+  ASSERT(CheckBnd(graph));
+
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+
+/*************************************************************************
+* This function selects the partition number and the queue from which
+* we will move vertices out
+**************************************************************************/ 
+int SelectQueueOneWay2(int ncon, float *pto, PQueueType queues[MAXNCON][2], float *ubvec)
+{
+  int i, cnum=-1, imax, maxgain;
+  float max=0.0;
+  float twgt[MAXNCON];
+
+  for (i=0; i<ncon; i++) {
+    if (max < pto[i]) {
+      imax = i;
+      max = pto[i];
+    }
+  }
+  for (i=0; i<ncon; i++) 
+    twgt[i] = (max/(ubvec[imax]*ubvec[i]))/pto[i];
+  twgt[imax] = 0.0;
+
+  max = 0.0;
+  for (i=0; i<ncon; i++) {
+    if (max < twgt[i] && (PQueueGetSize(&queues[i][0]) > 0 || PQueueGetSize(&queues[i][1]) > 0)) {
+      max = twgt[i];
+      cnum = i;
+    }
+  }
+  if (max > 1)
+    return cnum;
+
+  /* optimize of cut */
+  maxgain = -10000000;
+  for (i=0; i<ncon; i++) {
+    if (PQueueGetSize(&queues[i][0]) > 0 && PQueueGetKey(&queues[i][0]) > maxgain) {
+      maxgain = PQueueGetKey(&queues[i][0]);
+      cnum = i;
+    }
+  }
+
+  return cnum;
+
+}
+
diff --git a/Metis/mkmetis.c b/Metis/mkmetis.c
new file mode 100644
index 0000000000..ed270e1c1a
--- /dev/null
+++ b/Metis/mkmetis.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * mkmetis.c
+ *
+ * This file contains the top level routines for the multilevel k-way partitioning
+ * algorithm KMETIS.
+ *
+ * Started 7/28/97
+ * George
+ *
+ * $Id: mkmetis.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+
+/*************************************************************************
+* This function is the entry point for KWMETIS
+**************************************************************************/
+void METIS_mCPartGraphKway(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, 
+                          idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, 
+                          int *nparts, float *rubvec, int *options, int *edgecut, 
+                          idxtype *part)
+{
+  int i, j;
+  GraphType graph;
+  CtrlType ctrl;
+
+  if (*numflag == 1)
+    Change2CNumbering(*nvtxs, xadj, adjncy);
+
+  SetUpGraph(&graph, OP_KMETIS, *nvtxs, *ncon, xadj, adjncy, vwgt, adjwgt, *wgtflag);
+
+  if (options[0] == 0) {  /* Use the default parameters */
+    ctrl.CType  = McKMETIS_CTYPE;
+    ctrl.IType  = McKMETIS_ITYPE;
+    ctrl.RType  = McKMETIS_RTYPE;
+    ctrl.dbglvl = McKMETIS_DBGLVL;
+  }
+  else {
+    ctrl.CType  = options[OPTION_CTYPE];
+    ctrl.IType  = options[OPTION_ITYPE];
+    ctrl.RType  = options[OPTION_RTYPE];
+    ctrl.dbglvl = options[OPTION_DBGLVL];
+  }
+  ctrl.optype = OP_KMETIS;
+  ctrl.CoarsenTo = amax((*nvtxs)/(20*log2(*nparts)), 30*(*nparts));
+
+  ctrl.nmaxvwgt = 1.5/(1.0*ctrl.CoarsenTo);
+
+  InitRandom(-1);
+
+  AllocateWorkSpace(&ctrl, &graph, *nparts);
+
+  IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl));
+  IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr));
+
+  *edgecut = MCMlevelKWayPartitioning(&ctrl, &graph, *nparts, part, rubvec);
+
+  IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr));
+  IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl));
+
+  FreeWorkSpace(&ctrl, &graph);
+
+  if (*numflag == 1)
+    Change2FNumbering(*nvtxs, xadj, adjncy, part);
+}
+
+
+/*************************************************************************
+* This function takes a graph and produces a bisection of it
+**************************************************************************/
+int MCMlevelKWayPartitioning(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, 
+      float *rubvec)
+{
+  int i, j, nvtxs;
+  GraphType *cgraph;
+  int options[10], edgecut;
+
+  cgraph = MCCoarsen2Way(ctrl, graph);
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr));
+  MocAllocateKWayPartitionMemory(ctrl, cgraph, nparts);
+
+  options[0] = 1; 
+  options[OPTION_CTYPE] = MATCH_SBHEM_INFNORM;
+  options[OPTION_ITYPE] = IPART_RANDOM;
+  options[OPTION_RTYPE] = RTYPE_FM;
+  options[OPTION_DBGLVL] = 0;
+
+  /* Determine what you will use as the initial partitioner, based on tolerances */
+  for (i=0; i<graph->ncon; i++) {
+    if (rubvec[i] > 1.2)
+      break;
+  }
+  if (i == graph->ncon)
+    METIS_mCPartGraphRecursiveInternal(&cgraph->nvtxs, &cgraph->ncon, 
+          cgraph->xadj, cgraph->adjncy, cgraph->nvwgt, cgraph->adjwgt, &nparts, 
+          options, &edgecut, cgraph->where);
+  else
+    METIS_mCHPartGraphRecursiveInternal(&cgraph->nvtxs, &cgraph->ncon, 
+          cgraph->xadj, cgraph->adjncy, cgraph->nvwgt, cgraph->adjwgt, &nparts, 
+          rubvec, options, &edgecut, cgraph->where);
+
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr));
+  IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial %d-way partitioning cut: %d\n", nparts, edgecut));
+
+  IFSET(ctrl->dbglvl, DBG_KWAYPINFO, ComputePartitionInfo(cgraph, nparts, cgraph->where));
+
+  MocRefineKWayHorizontal(ctrl, graph, cgraph, nparts, rubvec);
+
+  idxcopy(graph->nvtxs, graph->where, part);
+
+  GKfree(&graph->nvwgt, &graph->npwgts, &graph->gdata, &graph->rdata, LTERM);
+
+  return graph->mincut;
+
+}
+
diff --git a/Metis/mkwayfmh.c b/Metis/mkwayfmh.c
new file mode 100644
index 0000000000..0d06ed0e38
--- /dev/null
+++ b/Metis/mkwayfmh.c
@@ -0,0 +1,677 @@
+/*
+ * mkwayfmh.c
+ *
+ * This file contains code that implements the multilevel k-way refinement
+ *
+ * Started 7/28/97
+ * George
+ *
+ * $Id: mkwayfmh.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+
+/*************************************************************************
+* This function performs k-way refinement
+**************************************************************************/
+void MCRandom_KWayEdgeRefineHorizontal(CtrlType *ctrl, GraphType *graph, int nparts, 
+       float *orgubvec, int npasses)
+{
+  int i, ii, iii, j, jj, k, l, pass, nvtxs, ncon, nmoves, nbnd, myndegrees, same; 
+  int from, me, to, oldcut, gain;
+  idxtype *xadj, *adjncy, *adjwgt;
+  idxtype *where, *perm, *bndptr, *bndind;
+  EDegreeType *myedegrees;
+  RInfoType *myrinfo;
+  float *npwgts, *nvwgt, *minwgt, *maxwgt, maxlb, minlb, ubvec[MAXNCON], tvec[MAXNCON];
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+
+  where = graph->where;
+  npwgts = graph->npwgts;
+  
+  /* Setup the weight intervals of the various subdomains */
+  minwgt =  fwspacemalloc(ctrl, nparts*ncon);
+  maxwgt = fwspacemalloc(ctrl, nparts*ncon);
+
+  /* See if the orgubvec consists of identical constraints */
+  maxlb = minlb = orgubvec[0];
+  for (i=1; i<ncon; i++) {
+    minlb = (orgubvec[i] < minlb ? orgubvec[i] : minlb);
+    maxlb = (orgubvec[i] > maxlb ? orgubvec[i] : maxlb);
+  }
+  same = (fabs(maxlb-minlb) < .01 ? 1 : 0);
+
+
+  /* Let's not get very optimistic. Let Balancing do the work */
+  ComputeHKWayLoadImbalance(ncon, nparts, npwgts, ubvec);
+  for (i=0; i<ncon; i++)
+    ubvec[i] = amax(ubvec[i], orgubvec[i]);
+
+  if (!same) {
+    for (i=0; i<nparts; i++) {
+      for (j=0; j<ncon; j++) {
+        maxwgt[i*ncon+j] = ubvec[j]/nparts;
+        minwgt[i*ncon+j] = 1.0/(ubvec[j]*nparts);
+      }
+    }
+  }
+  else {
+    maxlb = ubvec[0];
+    for (i=1; i<ncon; i++) 
+      maxlb = (ubvec[i] > maxlb ? ubvec[i] : maxlb);
+
+    for (i=0; i<nparts; i++) {
+      for (j=0; j<ncon; j++) {
+        maxwgt[i*ncon+j] = maxlb/nparts;
+        minwgt[i*ncon+j] = 1.0/(maxlb*nparts);
+      }
+    }
+  }
+
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+
+  if (ctrl->dbglvl&DBG_REFINE) {
+    printf("Partitions: [%5.4f %5.4f], Nv-Nb[%6d %6d]. Cut: %6d, LB: ",
+            npwgts[samin(ncon*nparts, npwgts)], npwgts[samax(ncon*nparts, npwgts)], 
+            graph->nvtxs, graph->nbnd, graph->mincut);
+    ComputeHKWayLoadImbalance(ncon, nparts, npwgts, tvec);
+    for (i=0; i<ncon; i++)
+      printf("%.3f ", tvec[i]);
+    printf("\n");
+  }
+
+  for (pass=0; pass<npasses; pass++) {
+    ASSERT(ComputeCut(graph, where) == graph->mincut);
+
+    oldcut = graph->mincut;
+    nbnd = graph->nbnd;
+
+    RandomPermute(nbnd, perm, 1);
+    for (nmoves=iii=0; iii<graph->nbnd; iii++) {
+      ii = perm[iii];
+      if (ii >= nbnd)
+        continue;
+      i = bndind[ii];
+
+      myrinfo = graph->rinfo+i;
+
+      if (myrinfo->ed >= myrinfo->id) { /* Total ED is too high */
+        from = where[i];
+        nvwgt = graph->nvwgt+i*ncon;
+
+        if (myrinfo->id > 0 && AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, -1.0, nvwgt, minwgt+from*ncon)) 
+          continue;   /* This cannot be moved! */
+
+        myedegrees = myrinfo->edegrees;
+        myndegrees = myrinfo->ndegrees;
+
+        for (k=0; k<myndegrees; k++) {
+          to = myedegrees[k].pid;
+          gain = myedegrees[k].ed - myrinfo->id; 
+          if (gain >= 0 && 
+              (AreAllHVwgtsBelow(ncon, 1.0, npwgts+to*ncon, 1.0, nvwgt, maxwgt+to*ncon) ||
+               IsHBalanceBetterFT(ncon, nparts, npwgts+from*ncon, npwgts+to*ncon, nvwgt, ubvec)))
+            break;
+        }
+        if (k == myndegrees)
+          continue;  /* break out if you did not find a candidate */
+
+        for (j=k+1; j<myndegrees; j++) {
+          to = myedegrees[j].pid;
+          if ((myedegrees[j].ed > myedegrees[k].ed &&
+               (AreAllHVwgtsBelow(ncon, 1.0, npwgts+to*ncon, 1.0, nvwgt, maxwgt+to*ncon) || 
+               IsHBalanceBetterFT(ncon, nparts, npwgts+from*ncon, npwgts+to*ncon, nvwgt, ubvec))) ||
+              (myedegrees[j].ed == myedegrees[k].ed && 
+               IsHBalanceBetterTT(ncon, nparts, npwgts+myedegrees[k].pid*ncon, npwgts+to*ncon, nvwgt, ubvec)))
+            k = j;
+        }
+
+        to = myedegrees[k].pid;
+
+        if (myedegrees[k].ed-myrinfo->id == 0 
+            && !IsHBalanceBetterFT(ncon, nparts, npwgts+from*ncon, npwgts+to*ncon, nvwgt, ubvec)
+            && AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, 0.0, npwgts+from*ncon, maxwgt+from*ncon)) 
+          continue;
+
+        /*=====================================================================
+        * If we got here, we can now move the vertex from 'from' to 'to' 
+        *======================================================================*/
+        graph->mincut -= myedegrees[k].ed-myrinfo->id;
+
+        IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut));
+
+        /* Update where, weight, and ID/ED information of the vertex you moved */
+        saxpy(ncon, 1.0, nvwgt, 1, npwgts+to*ncon, 1);
+        saxpy(ncon, -1.0, nvwgt, 1, npwgts+from*ncon, 1);
+        where[i] = to;
+        myrinfo->ed += myrinfo->id-myedegrees[k].ed;
+        SWAP(myrinfo->id, myedegrees[k].ed, j);
+        if (myedegrees[k].ed == 0) 
+          myedegrees[k] = myedegrees[--myrinfo->ndegrees];
+        else
+          myedegrees[k].pid = from;
+
+        if (myrinfo->ed-myrinfo->id < 0)
+          BNDDelete(nbnd, bndind, bndptr, i);
+
+        /* Update the degrees of adjacent vertices */
+        for (j=xadj[i]; j<xadj[i+1]; j++) {
+          ii = adjncy[j];
+          me = where[ii];
+
+          myrinfo = graph->rinfo+ii;
+          if (myrinfo->edegrees == NULL) {
+            myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree;
+            ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii];
+          }
+          myedegrees = myrinfo->edegrees;
+
+          ASSERT(CheckRInfo(myrinfo));
+
+          if (me == from) {
+            INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]);
+
+            if (myrinfo->ed-myrinfo->id >= 0 && bndptr[ii] == -1)
+              BNDInsert(nbnd, bndind, bndptr, ii);
+          }
+          else if (me == to) {
+            INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]);
+
+            if (myrinfo->ed-myrinfo->id < 0 && bndptr[ii] != -1)
+              BNDDelete(nbnd, bndind, bndptr, ii);
+          }
+
+          /* Remove contribution from the .ed of 'from' */
+          if (me != from) {
+            for (k=0; k<myrinfo->ndegrees; k++) {
+              if (myedegrees[k].pid == from) {
+                if (myedegrees[k].ed == adjwgt[j])
+                  myedegrees[k] = myedegrees[--myrinfo->ndegrees];
+                else
+                  myedegrees[k].ed -= adjwgt[j];
+                break;
+              }
+            }
+          }
+
+          /* Add contribution to the .ed of 'to' */
+          if (me != to) {
+            for (k=0; k<myrinfo->ndegrees; k++) {
+              if (myedegrees[k].pid == to) {
+                myedegrees[k].ed += adjwgt[j];
+                break;
+              }
+            }
+            if (k == myrinfo->ndegrees) {
+              myedegrees[myrinfo->ndegrees].pid = to;
+              myedegrees[myrinfo->ndegrees++].ed = adjwgt[j];
+            }
+          }
+
+          ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]);
+          ASSERT(CheckRInfo(myrinfo));
+
+        }
+        nmoves++;
+      }
+    }
+
+    graph->nbnd = nbnd;
+
+    if (ctrl->dbglvl&DBG_REFINE) {
+      printf("\t [%5.4f %5.4f], Nb: %6d, Nmoves: %5d, Cut: %6d, LB: ",
+              npwgts[samin(ncon*nparts, npwgts)], npwgts[samax(ncon*nparts, npwgts)], 
+              nbnd, nmoves, graph->mincut);
+      ComputeHKWayLoadImbalance(ncon, nparts, npwgts, tvec);
+      for (i=0; i<ncon; i++)
+        printf("%.3f ", tvec[i]);
+      printf("\n");
+    }
+
+    if (graph->mincut == oldcut)
+      break;
+  }
+
+  fwspacefree(ctrl, ncon*nparts);
+  fwspacefree(ctrl, ncon*nparts);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+
+/*************************************************************************
+* This function performs k-way refinement
+**************************************************************************/
+void MCGreedy_KWayEdgeBalanceHorizontal(CtrlType *ctrl, GraphType *graph, int nparts, 
+       float *ubvec, int npasses)
+{
+  int i, ii, iii, j, jj, k, l, pass, nvtxs, ncon, nbnd, myndegrees, oldgain, gain, nmoves; 
+  int from, me, to, oldcut;
+  idxtype *xadj, *adjncy, *adjwgt;
+  idxtype *where, *perm, *bndptr, *bndind, *moved;
+  EDegreeType *myedegrees;
+  RInfoType *myrinfo;
+  PQueueType queue;
+  float *npwgts, *nvwgt, *minwgt, *maxwgt, tvec[MAXNCON];
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  bndind = graph->bndind;
+  bndptr = graph->bndptr;
+
+  where = graph->where;
+  npwgts = graph->npwgts;
+  
+  /* Setup the weight intervals of the various subdomains */
+  minwgt =  fwspacemalloc(ctrl, ncon*nparts);
+  maxwgt = fwspacemalloc(ctrl, ncon*nparts);
+
+  for (i=0; i<nparts; i++) {
+    for (j=0; j<ncon; j++) {
+      maxwgt[i*ncon+j] = ubvec[j]/nparts;
+      minwgt[i*ncon+j] = 1.0/(ubvec[j]*nparts);
+    }
+  }
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  moved = idxwspacemalloc(ctrl, nvtxs);
+
+  PQueueInit(ctrl, &queue, nvtxs, graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]);
+
+  if (ctrl->dbglvl&DBG_REFINE) {
+    printf("Partitions: [%5.4f %5.4f], Nv-Nb[%6d %6d]. Cut: %6d, LB: ",
+            npwgts[samin(ncon*nparts, npwgts)], npwgts[samax(ncon*nparts, npwgts)], 
+            graph->nvtxs, graph->nbnd, graph->mincut);
+    ComputeHKWayLoadImbalance(ncon, nparts, npwgts, tvec);
+    for (i=0; i<ncon; i++)
+      printf("%.3f ", tvec[i]);
+    printf("[B]\n");
+  }
+
+
+  for (pass=0; pass<npasses; pass++) {
+    ASSERT(ComputeCut(graph, where) == graph->mincut);
+
+    /* Check to see if things are out of balance, given the tolerance */
+    if (MocIsHBalanced(ncon, nparts, npwgts, ubvec))
+      break;
+
+    PQueueReset(&queue);
+    idxset(nvtxs, -1, moved);
+
+    oldcut = graph->mincut;
+    nbnd = graph->nbnd;
+
+    RandomPermute(nbnd, perm, 1);
+    for (ii=0; ii<nbnd; ii++) {
+      i = bndind[perm[ii]];
+      PQueueInsert(&queue, i, graph->rinfo[i].ed - graph->rinfo[i].id);
+      moved[i] = 2;
+    }
+
+    nmoves = 0;
+    for (;;) {
+      if ((i = PQueueGetMax(&queue)) == -1) 
+        break;
+      moved[i] = 1;
+
+      myrinfo = graph->rinfo+i;
+      from = where[i];
+      nvwgt = graph->nvwgt+i*ncon;
+
+      if (AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, -1.0, nvwgt, minwgt+from*ncon))
+        continue;   /* This cannot be moved! */
+
+      myedegrees = myrinfo->edegrees;
+      myndegrees = myrinfo->ndegrees;
+
+      for (k=0; k<myndegrees; k++) {
+        to = myedegrees[k].pid;
+        if (IsHBalanceBetterFT(ncon, nparts, npwgts+from*ncon, npwgts+to*ncon, nvwgt, ubvec))
+          break;
+      }
+      if (k == myndegrees) 
+        continue;  /* break out if you did not find a candidate */
+
+      for (j=k+1; j<myndegrees; j++) {
+        to = myedegrees[j].pid;
+        if (IsHBalanceBetterTT(ncon, nparts, npwgts+myedegrees[k].pid*ncon, npwgts+to*ncon, nvwgt, ubvec)) 
+          k = j;
+      }
+
+      to = myedegrees[k].pid;
+
+      j = 0;
+      if (!AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, 0.0, nvwgt, maxwgt+from*ncon))
+        j++;
+      if (myedegrees[k].ed-myrinfo->id >= 0)
+        j++;
+      if (!AreAllHVwgtsAbove(ncon, 1.0, npwgts+to*ncon, 0.0, nvwgt, minwgt+to*ncon) &&
+          AreAllHVwgtsBelow(ncon, 1.0, npwgts+to*ncon, 1.0, nvwgt, maxwgt+to*ncon))
+        j++;
+      if (j == 0)
+        continue;
+
+/* DELETE
+      if (myedegrees[k].ed-myrinfo->id < 0 && 
+          AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, 0.0, nvwgt, maxwgt+from*ncon) &&
+          AreAllHVwgtsAbove(ncon, 1.0, npwgts+to*ncon, 0.0, nvwgt, minwgt+to*ncon) &&
+          AreAllHVwgtsBelow(ncon, 1.0, npwgts+to*ncon, 1.0, nvwgt, maxwgt+to*ncon))
+        continue;
+*/
+      /*=====================================================================
+      * If we got here, we can now move the vertex from 'from' to 'to' 
+      *======================================================================*/
+      graph->mincut -= myedegrees[k].ed-myrinfo->id;
+
+      IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut));
+
+      /* Update where, weight, and ID/ED information of the vertex you moved */
+      saxpy(ncon, 1.0, nvwgt, 1, npwgts+to*ncon, 1);
+      saxpy(ncon, -1.0, nvwgt, 1, npwgts+from*ncon, 1);
+      where[i] = to;
+      myrinfo->ed += myrinfo->id-myedegrees[k].ed;
+      SWAP(myrinfo->id, myedegrees[k].ed, j);
+      if (myedegrees[k].ed == 0) 
+        myedegrees[k] = myedegrees[--myrinfo->ndegrees];
+      else
+        myedegrees[k].pid = from;
+
+      if (myrinfo->ed == 0)
+        BNDDelete(nbnd, bndind, bndptr, i);
+
+      /* Update the degrees of adjacent vertices */
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        ii = adjncy[j];
+        me = where[ii];
+
+        myrinfo = graph->rinfo+ii;
+        if (myrinfo->edegrees == NULL) {
+          myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree;
+          ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii];
+        }
+        myedegrees = myrinfo->edegrees;
+
+        ASSERT(CheckRInfo(myrinfo));
+
+        oldgain = (myrinfo->ed-myrinfo->id);
+
+        if (me == from) {
+          INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]);
+
+          if (myrinfo->ed > 0 && bndptr[ii] == -1)
+            BNDInsert(nbnd, bndind, bndptr, ii);
+        }
+        else if (me == to) {
+          INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]);
+
+          if (myrinfo->ed == 0 && bndptr[ii] != -1)
+            BNDDelete(nbnd, bndind, bndptr, ii);
+        }
+
+        /* Remove contribution from the .ed of 'from' */
+        if (me != from) {
+          for (k=0; k<myrinfo->ndegrees; k++) {
+            if (myedegrees[k].pid == from) {
+              if (myedegrees[k].ed == adjwgt[j])
+                myedegrees[k] = myedegrees[--myrinfo->ndegrees];
+              else
+                myedegrees[k].ed -= adjwgt[j];
+              break;
+            }
+          }
+        }
+
+        /* Add contribution to the .ed of 'to' */
+        if (me != to) {
+          for (k=0; k<myrinfo->ndegrees; k++) {
+            if (myedegrees[k].pid == to) {
+              myedegrees[k].ed += adjwgt[j];
+              break;
+            }
+          }
+          if (k == myrinfo->ndegrees) {
+            myedegrees[myrinfo->ndegrees].pid = to;
+            myedegrees[myrinfo->ndegrees++].ed = adjwgt[j];
+          }
+        }
+
+
+        /* Update the queue */
+        if (me == to || me == from) { 
+          gain = myrinfo->ed-myrinfo->id;
+          if (moved[ii] == 2) {
+            if (myrinfo->ed > 0)
+              PQueueUpdate(&queue, ii, oldgain, gain);
+            else {
+              PQueueDelete(&queue, ii, oldgain);
+              moved[ii] = -1;
+            }
+          }
+          else if (moved[ii] == -1 && myrinfo->ed > 0) {
+            PQueueInsert(&queue, ii, gain);
+            moved[ii] = 2;
+          }
+        } 
+
+        ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]);
+        ASSERT(CheckRInfo(myrinfo));
+      }
+      nmoves++;
+    }
+
+    graph->nbnd = nbnd;
+
+    if (ctrl->dbglvl&DBG_REFINE) {
+      printf("\t [%5.4f %5.4f], Nb: %6d, Nmoves: %5d, Cut: %6d, LB: ",
+              npwgts[samin(ncon*nparts, npwgts)], npwgts[samax(ncon*nparts, npwgts)], 
+              nbnd, nmoves, graph->mincut);
+      ComputeHKWayLoadImbalance(ncon, nparts, npwgts, tvec);
+      for (i=0; i<ncon; i++)
+        printf("%.3f ", tvec[i]);
+      printf("\n");
+    }
+
+    if (nmoves == 0)
+      break;
+  }
+
+  PQueueFree(ctrl, &queue);
+
+  fwspacefree(ctrl, ncon*nparts);
+  fwspacefree(ctrl, ncon*nparts);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+
+}
+
+
+
+
+
+/*************************************************************************
+* This function checks if the vertex weights of two vertices are below 
+* a given set of values
+**************************************************************************/
+int AreAllHVwgtsBelow(int ncon, float alpha, float *vwgt1, float beta, float *vwgt2, float *limit)
+{
+  int i;
+
+  for (i=0; i<ncon; i++)
+    if (alpha*vwgt1[i] + beta*vwgt2[i] > limit[i])
+      return 0;
+
+  return 1;
+}
+
+
+
+/*************************************************************************
+* This function checks if the vertex weights of two vertices are above 
+* a given set of values
+**************************************************************************/
+int AreAllHVwgtsAbove(int ncon, float alpha, float *vwgt1, float beta, float *vwgt2, float *limit)
+{
+  int i;
+
+  for (i=0; i<ncon; i++)
+    if (alpha*vwgt1[i] + beta*vwgt2[i] < limit[i])
+      return 0;
+
+  return 1;
+}
+
+
+/*************************************************************************
+* This function computes the load imbalance over all the constrains
+* For now assume that we just want balanced partitionings
+**************************************************************************/ 
+void ComputeHKWayLoadImbalance(int ncon, int nparts, float *npwgts, float *lbvec)
+{
+  int i, j;
+  float max;
+
+  for (i=0; i<ncon; i++) {
+    max = 0.0;
+    for (j=0; j<nparts; j++) {
+      if (npwgts[j*ncon+i] > max)
+        max = npwgts[j*ncon+i];
+    }
+
+    lbvec[i] = max*nparts;
+  }
+}
+
+
+/*************************************************************************
+* This function determines if a partitioning is horizontally balanced
+**************************************************************************/
+int MocIsHBalanced(int ncon, int nparts, float *npwgts, float *ubvec)
+{
+  int i, j;
+  float max;
+
+  for (i=0; i<ncon; i++) {
+    max = 0.0;
+    for (j=0; j<nparts; j++) {
+      if (npwgts[j*ncon+i] > max)
+        max = npwgts[j*ncon+i];
+    }
+
+    if (ubvec[i] < max*nparts)
+      return 0;
+  }
+
+  return 1;
+}
+
+
+
+
+
+/*************************************************************************
+* This function checks if the pairwise balance of the between the two 
+* partitions will improve by moving the vertex v from pfrom to pto,
+* subject to the target partition weights of tfrom, and tto respectively
+**************************************************************************/
+int IsHBalanceBetterFT(int ncon, int nparts, float *pfrom, float *pto, float *vwgt, float *ubvec)
+{
+  int i, j, k;
+  float blb1=0.0, alb1=0.0, sblb=0.0, salb=0.0;
+  float blb2=0.0, alb2=0.0;
+  float temp;
+
+  for (i=0; i<ncon; i++) {
+    temp = amax(pfrom[i], pto[i])*nparts/ubvec[i];
+    if (blb1 < temp) {
+      blb2 = blb1;
+      blb1 = temp;
+    }
+    else if (blb2 < temp)
+      blb2 = temp;
+    sblb += temp;
+
+    temp = amax(pfrom[i]-vwgt[i], pto[i]+vwgt[i])*nparts/ubvec[i];
+    if (alb1 < temp) {
+      alb2 = alb1;
+      alb1 = temp;
+    }
+    else if (alb2 < temp)
+      alb2 = temp;
+    salb += temp;
+  }
+
+  if (alb1 < blb1)
+    return 1;
+  if (blb1 < alb1)
+    return 0;
+  if (alb2 < blb2)
+    return 1;
+  if (blb2 < alb2)
+    return 0;
+  
+  return salb < sblb;
+
+}
+
+
+
+
+/*************************************************************************
+* This function checks if it will be better to move a vertex to pt2 than
+* to pt1 subject to their target weights of tt1 and tt2, respectively
+* This routine takes into account the weight of the vertex in question
+**************************************************************************/
+int IsHBalanceBetterTT(int ncon, int nparts, float *pt1, float *pt2, float *vwgt, float *ubvec)
+{
+  int i;
+  float m11=0.0, m12=0.0, m21=0.0, m22=0.0, sm1=0.0, sm2=0.0, temp;
+
+  for (i=0; i<ncon; i++) {
+    temp = (pt1[i]+vwgt[i])*nparts/ubvec[i];
+    if (m11 < temp) {
+      m12 = m11;
+      m11 = temp;
+    }
+    else if (m12 < temp)
+      m12 = temp;
+    sm1 += temp;
+
+    temp = (pt2[i]+vwgt[i])*nparts/ubvec[i];
+    if (m21 < temp) {
+      m22 = m21;
+      m21 = temp;
+    }
+    else if (m22 < temp)
+      m22 = temp;
+    sm2 += temp;
+  }
+
+  if (m21 < m11)
+    return 1;
+  if (m21 > m11)
+    return 0;
+  if (m22 < m12)
+    return 1;
+  if (m22 > m12)
+    return 0;
+
+  return sm2 < sm1;  
+}
+
diff --git a/Metis/mkwayrefine.c b/Metis/mkwayrefine.c
new file mode 100644
index 0000000000..0984ad707d
--- /dev/null
+++ b/Metis/mkwayrefine.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * mkwayrefine.c
+ *
+ * This file contains the driving routines for multilevel k-way refinement
+ *
+ * Started 7/28/97
+ * George
+ *
+ * $Id: mkwayrefine.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function is the entry point of refinement
+**************************************************************************/
+void MocRefineKWayHorizontal(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, int nparts, 
+       float *ubvec)
+{
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr));
+
+  /* Compute the parameters of the coarsest graph */
+  MocComputeKWayPartitionParams(ctrl, graph, nparts);
+
+  for (;;) {
+    IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr));
+
+    if (!MocIsHBalanced(graph->ncon, nparts, graph->npwgts, ubvec)) {
+      MocComputeKWayBalanceBoundary(ctrl, graph, nparts);
+      MCGreedy_KWayEdgeBalanceHorizontal(ctrl, graph, nparts, ubvec, 4); 
+      ComputeKWayBoundary(ctrl, graph, nparts);
+    }
+
+    MCRandom_KWayEdgeRefineHorizontal(ctrl, graph, nparts, ubvec, 10); 
+
+    IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr));
+
+    if (graph == orggraph)
+      break;
+
+    graph = graph->finer;
+    IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr));
+    MocProjectKWayPartition(ctrl, graph, nparts);
+    IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr));
+  }
+
+  if (!MocIsHBalanced(graph->ncon, nparts, graph->npwgts, ubvec)) {
+    MocComputeKWayBalanceBoundary(ctrl, graph, nparts);
+    MCGreedy_KWayEdgeBalanceHorizontal(ctrl, graph, nparts, ubvec, 4); 
+    ComputeKWayBoundary(ctrl, graph, nparts);
+    MCRandom_KWayEdgeRefineHorizontal(ctrl, graph, nparts, ubvec, 10); 
+  }
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr));
+}
+
+
+
+
+/*************************************************************************
+* This function allocates memory for k-way edge refinement
+**************************************************************************/
+void MocAllocateKWayPartitionMemory(CtrlType *ctrl, GraphType *graph, int nparts)
+{
+  int nvtxs, ncon, pad64;
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+
+  pad64 = (3*nvtxs)%2;
+
+  graph->rdata = idxmalloc(3*nvtxs+(sizeof(RInfoType)/sizeof(idxtype))*nvtxs+pad64, "AllocateKWayPartitionMemory: rdata");
+  graph->where          = graph->rdata;
+  graph->bndptr         = graph->rdata + nvtxs;
+  graph->bndind         = graph->rdata + 2*nvtxs;
+  graph->rinfo          = (RInfoType *)(graph->rdata + 3*nvtxs + pad64);
+
+  graph->npwgts         = fmalloc(ncon*nparts, "MocAllocateKWayPartitionMemory: npwgts");
+}
+
+
+/*************************************************************************
+* This function computes the initial id/ed 
+**************************************************************************/
+void MocComputeKWayPartitionParams(CtrlType *ctrl, GraphType *graph, int nparts)
+{
+  int i, j, k, l, nvtxs, ncon, nbnd, mincut, me, other;
+  idxtype *xadj, *adjncy, *adjwgt, *where, *bndind, *bndptr;
+  RInfoType *rinfo, *myrinfo;
+  EDegreeType *myedegrees;
+  float *nvwgt, *npwgts;
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  xadj = graph->xadj;
+  nvwgt = graph->nvwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  where = graph->where;
+  npwgts = sset(ncon*nparts, 0.0, graph->npwgts);
+  bndind = graph->bndind;
+  bndptr = idxset(nvtxs, -1, graph->bndptr);
+  rinfo = graph->rinfo;
+
+
+  /*------------------------------------------------------------
+  / Compute now the id/ed degrees
+  /------------------------------------------------------------*/
+  ctrl->wspace.cdegree = 0;
+  nbnd = mincut = 0;
+  for (i=0; i<nvtxs; i++) {
+    me = where[i];
+    saxpy(ncon, 1.0, nvwgt+i*ncon, 1, npwgts+me*ncon, 1);
+
+    myrinfo = rinfo+i;
+    myrinfo->id = myrinfo->ed = myrinfo->ndegrees = 0;
+    myrinfo->edegrees = NULL;
+
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      if (me != where[adjncy[j]])
+        myrinfo->ed += adjwgt[j];
+    }
+    myrinfo->id = graph->adjwgtsum[i] - myrinfo->ed;
+
+    if (myrinfo->ed > 0) 
+      mincut += myrinfo->ed;
+
+    if (myrinfo->ed-myrinfo->id >= 0)
+      BNDInsert(nbnd, bndind, bndptr, i);
+
+    /* Time to compute the particular external degrees */
+    if (myrinfo->ed > 0) { 
+      myedegrees = myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree;
+      ctrl->wspace.cdegree += xadj[i+1]-xadj[i];
+
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        other = where[adjncy[j]];
+        if (me != other) {
+          for (k=0; k<myrinfo->ndegrees; k++) {
+            if (myedegrees[k].pid == other) {
+              myedegrees[k].ed += adjwgt[j];
+              break;
+            }
+          }
+          if (k == myrinfo->ndegrees) {
+            myedegrees[myrinfo->ndegrees].pid = other;
+            myedegrees[myrinfo->ndegrees++].ed = adjwgt[j];
+          }
+        }
+      }
+
+      ASSERT(myrinfo->ndegrees <= xadj[i+1]-xadj[i]);
+    }
+  }
+
+  graph->mincut = mincut/2;
+  graph->nbnd = nbnd;
+
+}
+
+
+
+/*************************************************************************
+* This function projects a partition, and at the same time computes the
+* parameters for refinement.
+**************************************************************************/
+void MocProjectKWayPartition(CtrlType *ctrl, GraphType *graph, int nparts)
+{
+  int i, j, k, nvtxs, nbnd, me, other, istart, iend, ndegrees;
+  idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum;
+  idxtype *cmap, *where, *bndptr, *bndind;
+  idxtype *cwhere;
+  GraphType *cgraph;
+  RInfoType *crinfo, *rinfo, *myrinfo;
+  EDegreeType *myedegrees;
+  idxtype *htable;
+
+  cgraph = graph->coarser;
+  cwhere = cgraph->where;
+  crinfo = cgraph->rinfo;
+
+  nvtxs = graph->nvtxs;
+  cmap = graph->cmap;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+  adjwgtsum = graph->adjwgtsum;
+
+  MocAllocateKWayPartitionMemory(ctrl, graph, nparts);
+  where = graph->where;
+  rinfo = graph->rinfo;
+  bndind = graph->bndind;
+  bndptr = idxset(nvtxs, -1, graph->bndptr);
+
+  /* Go through and project partition and compute id/ed for the nodes */
+  for (i=0; i<nvtxs; i++) {
+    k = cmap[i];
+    where[i] = cwhere[k];
+    cmap[i] = crinfo[k].ed;  /* For optimization */
+  }
+
+  htable = idxset(nparts, -1, idxwspacemalloc(ctrl, nparts));
+
+  ctrl->wspace.cdegree = 0;
+  for (nbnd=0, i=0; i<nvtxs; i++) {
+    me = where[i];
+
+    myrinfo = rinfo+i;
+    myrinfo->id = myrinfo->ed = myrinfo->ndegrees = 0;
+    myrinfo->edegrees = NULL;
+
+    myrinfo->id = adjwgtsum[i];
+
+    if (cmap[i] > 0) { /* If it is an interface node. Note cmap[i] = crinfo[cmap[i]].ed */
+      istart = xadj[i];
+      iend = xadj[i+1];
+
+      myedegrees = myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree;
+      ctrl->wspace.cdegree += iend-istart;
+
+      ndegrees = 0;
+      for (j=istart; j<iend; j++) {
+        other = where[adjncy[j]];
+        if (me != other) {
+          myrinfo->ed += adjwgt[j];
+          if ((k = htable[other]) == -1) {
+            htable[other] = ndegrees;
+            myedegrees[ndegrees].pid = other;
+            myedegrees[ndegrees++].ed = adjwgt[j];
+          }
+          else {
+            myedegrees[k].ed += adjwgt[j];
+          }
+        }
+      }
+      myrinfo->id -= myrinfo->ed;
+
+      /* Remove space for edegrees if it was interior */
+      if (myrinfo->ed == 0) { 
+        myrinfo->edegrees = NULL;
+        ctrl->wspace.cdegree -= iend-istart;
+      }
+      else {
+        if (myrinfo->ed-myrinfo->id >= 0) 
+          BNDInsert(nbnd, bndind, bndptr, i); 
+
+        myrinfo->ndegrees = ndegrees;
+
+        for (j=0; j<ndegrees; j++)
+          htable[myedegrees[j].pid] = -1;
+      }
+    }
+  }
+
+  scopy(graph->ncon*nparts, cgraph->npwgts, graph->npwgts);
+  graph->mincut = cgraph->mincut;
+  graph->nbnd = nbnd;
+
+  FreeGraph(graph->coarser);
+  graph->coarser = NULL;
+
+  idxwspacefree(ctrl, nparts);
+
+  ASSERT(CheckBnd2(graph));
+
+}
+
+
+
+/*************************************************************************
+* This function computes the boundary definition for balancing
+**************************************************************************/
+void MocComputeKWayBalanceBoundary(CtrlType *ctrl, GraphType *graph, int nparts)
+{
+  int i, nvtxs, nbnd;
+  idxtype *bndind, *bndptr;
+
+  nvtxs = graph->nvtxs;
+  bndind = graph->bndind;
+  bndptr = idxset(nvtxs, -1, graph->bndptr);
+
+
+  /* Compute the new boundary */
+  nbnd = 0;
+  for (i=0; i<nvtxs; i++) {
+    if (graph->rinfo[i].ed > 0) 
+      BNDInsert(nbnd, bndind, bndptr, i);
+  }
+
+  graph->nbnd = nbnd;
+}
+
diff --git a/Metis/mmatch.c b/Metis/mmatch.c
new file mode 100644
index 0000000000..45259570d4
--- /dev/null
+++ b/Metis/mmatch.c
@@ -0,0 +1,506 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * mmatch.c
+ *
+ * This file contains the code that computes matchings and creates the next
+ * level coarse graph.
+ *
+ * Started 7/23/97
+ * George
+ *
+ * $Id: mmatch.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function finds a matching using the HEM heuristic
+**************************************************************************/
+void MCMatch_RM(CtrlType *ctrl, GraphType *graph)
+{
+  int i, ii, j, k, nvtxs, ncon, cnvtxs, maxidx;
+  idxtype *xadj, *adjncy, *adjwgt;
+  idxtype *match, *cmap, *perm;
+  float *nvwgt;
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr));
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  xadj = graph->xadj;
+  nvwgt = graph->nvwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  cmap = graph->cmap;
+  match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs));
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  RandomPermute(nvtxs, perm, 1);
+
+  cnvtxs = 0;
+  for (ii=0; ii<nvtxs; ii++) {
+    i = perm[ii];
+
+    if (match[i] == UNMATCHED) {  /* Unmatched */
+      maxidx = i;
+
+      /* Find a random matching, subject to maxvwgt constraints */
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        k = adjncy[j];
+        if (match[k] == UNMATCHED && AreAllVwgtsBelowFast(ncon, nvwgt+i*ncon, nvwgt+k*ncon, ctrl->nmaxvwgt)) {
+          maxidx = k;
+          break;
+        }
+      }
+
+      cmap[i] = cmap[maxidx] = cnvtxs++;
+      match[i] = maxidx;
+      match[maxidx] = i;
+    }
+  }
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr));
+
+  CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm);
+
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+
+/*************************************************************************
+* This function finds a matching using the HEM heuristic
+**************************************************************************/
+void MCMatch_HEM(CtrlType *ctrl, GraphType *graph)
+{
+  int i, ii, j, k, l, nvtxs, cnvtxs, ncon, maxidx, maxwgt;
+  idxtype *xadj, *adjncy, *adjwgt;
+  idxtype *match, *cmap, *perm;
+  float *nvwgt;
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr));
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  xadj = graph->xadj;
+  nvwgt = graph->nvwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  cmap = graph->cmap;
+  match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs));
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  RandomPermute(nvtxs, perm, 1);
+
+  cnvtxs = 0;
+  for (ii=0; ii<nvtxs; ii++) {
+    i = perm[ii];
+
+    if (match[i] == UNMATCHED) {  /* Unmatched */
+      maxidx = i;
+      maxwgt = 0;
+
+      /* Find a heavy-edge matching, subject to maxvwgt constraints */
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        k = adjncy[j];
+        if (match[k] == UNMATCHED && maxwgt <= adjwgt[j] &&
+               AreAllVwgtsBelowFast(ncon, nvwgt+i*ncon, nvwgt+k*ncon, ctrl->nmaxvwgt)) {
+          maxwgt = adjwgt[j];
+          maxidx = adjncy[j];
+        }
+      }
+
+      cmap[i] = cmap[maxidx] = cnvtxs++;
+      match[i] = maxidx;
+      match[maxidx] = i;
+    }
+  }
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr));
+
+  CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm);
+
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+
+/*************************************************************************
+* This function finds a matching using the HEM heuristic
+**************************************************************************/
+void MCMatch_SHEM(CtrlType *ctrl, GraphType *graph)
+{
+  int i, ii, j, k, nvtxs, cnvtxs, ncon, maxidx, maxwgt, avgdegree;
+  idxtype *xadj, *adjncy, *adjwgt;
+  idxtype *match, *cmap, *degrees, *perm, *tperm;
+  float *nvwgt;
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr));
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  xadj = graph->xadj;
+  nvwgt = graph->nvwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  cmap = graph->cmap;
+  match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs));
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  tperm = idxwspacemalloc(ctrl, nvtxs);
+  degrees = idxwspacemalloc(ctrl, nvtxs);
+
+  RandomPermute(nvtxs, tperm, 1);
+  avgdegree = 0.7*(xadj[nvtxs]/nvtxs);
+  for (i=0; i<nvtxs; i++) 
+    degrees[i] = (xadj[i+1]-xadj[i] > avgdegree ? avgdegree : xadj[i+1]-xadj[i]);
+  BucketSortKeysInc(nvtxs, avgdegree, degrees, tperm, perm);
+
+  cnvtxs = 0;
+
+  /* Take care any islands. Islands are matched with non-islands due to coarsening */
+  for (ii=0; ii<nvtxs; ii++) {
+    i = perm[ii];
+
+    if (match[i] == UNMATCHED) {  /* Unmatched */
+      if (xadj[i] < xadj[i+1])
+        break;
+
+      maxidx = i;
+      for (j=nvtxs-1; j>ii; j--) {
+        k = perm[j];
+        if (match[k] == UNMATCHED && xadj[k] < xadj[k+1]) {
+          maxidx = k;
+          break;
+        }
+      }
+
+      cmap[i] = cmap[maxidx] = cnvtxs++;
+      match[i] = maxidx;
+      match[maxidx] = i;
+    }
+  }
+
+  /* Continue with normal matching */
+  for (; ii<nvtxs; ii++) {
+    i = perm[ii];
+
+    if (match[i] == UNMATCHED) {  /* Unmatched */
+      maxidx = i;
+      maxwgt = 0;
+
+      /* Find a heavy-edge matching, subject to maxvwgt constraints */
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        k = adjncy[j];
+        if (match[k] == UNMATCHED && maxwgt <= adjwgt[j] &&
+               AreAllVwgtsBelowFast(ncon, nvwgt+i*ncon, nvwgt+k*ncon, ctrl->nmaxvwgt)) {
+          maxwgt = adjwgt[j];
+          maxidx = adjncy[j];
+        }
+      }
+
+      cmap[i] = cmap[maxidx] = cnvtxs++;
+      match[i] = maxidx;
+      match[maxidx] = i;
+    }
+  }
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr));
+
+  idxwspacefree(ctrl, nvtxs);  /* degrees */
+  idxwspacefree(ctrl, nvtxs);  /* tperm */
+
+  CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm);
+
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+
+/*************************************************************************
+* This function finds a matching using the HEM heuristic
+**************************************************************************/
+void MCMatch_SHEBM(CtrlType *ctrl, GraphType *graph, int norm)
+{
+  int i, ii, j, k, nvtxs, cnvtxs, ncon, maxidx, maxwgt, avgdegree;
+  idxtype *xadj, *adjncy, *adjwgt;
+  idxtype *match, *cmap, *degrees, *perm, *tperm;
+  float *nvwgt;
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr));
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  xadj = graph->xadj;
+  nvwgt = graph->nvwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  cmap = graph->cmap;
+  match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs));
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  tperm = idxwspacemalloc(ctrl, nvtxs);
+  degrees = idxwspacemalloc(ctrl, nvtxs);
+
+  RandomPermute(nvtxs, tperm, 1);
+  avgdegree = 0.7*(xadj[nvtxs]/nvtxs);
+  for (i=0; i<nvtxs; i++) 
+    degrees[i] = (xadj[i+1]-xadj[i] > avgdegree ? avgdegree : xadj[i+1]-xadj[i]);
+  BucketSortKeysInc(nvtxs, avgdegree, degrees, tperm, perm);
+
+  cnvtxs = 0;
+
+  /* Take care any islands. Islands are matched with non-islands due to coarsening */
+  for (ii=0; ii<nvtxs; ii++) {
+    i = perm[ii];
+
+    if (match[i] == UNMATCHED) {  /* Unmatched */
+      if (xadj[i] < xadj[i+1])
+        break;
+
+      maxidx = i;
+      for (j=nvtxs-1; j>ii; j--) {
+        k = perm[j];
+        if (match[k] == UNMATCHED && xadj[k] < xadj[k+1]) {
+          maxidx = k;
+          break;
+        }
+      }
+
+      cmap[i] = cmap[maxidx] = cnvtxs++;
+      match[i] = maxidx;
+      match[maxidx] = i;
+    }
+  }
+
+  /* Continue with normal matching */
+  for (; ii<nvtxs; ii++) {
+    i = perm[ii];
+
+    if (match[i] == UNMATCHED) {  /* Unmatched */
+      maxidx = i;
+      maxwgt = -1;
+
+      /* Find a heavy-edge matching, subject to maxvwgt constraints */
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        k = adjncy[j];
+
+        if (match[k] == UNMATCHED && 
+            AreAllVwgtsBelowFast(ncon, nvwgt+i*ncon, nvwgt+k*ncon, ctrl->nmaxvwgt) &&
+            (maxwgt < adjwgt[j] || 
+              (maxwgt == adjwgt[j] && 
+               BetterVBalance(ncon, norm, nvwgt+i*ncon, nvwgt+maxidx*ncon, nvwgt+k*ncon) >= 0
+              )
+            )
+           ) {
+          maxwgt = adjwgt[j];
+          maxidx = k;
+        }
+      }
+
+      cmap[i] = cmap[maxidx] = cnvtxs++;
+      match[i] = maxidx;
+      match[maxidx] = i;
+    }
+  }
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr));
+
+  idxwspacefree(ctrl, nvtxs);  /* degrees */
+  idxwspacefree(ctrl, nvtxs);  /* tperm */
+
+  CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm);
+
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+
+/*************************************************************************
+* This function finds a matching using the HEM heuristic
+**************************************************************************/
+void MCMatch_SBHEM(CtrlType *ctrl, GraphType *graph, int norm)
+{
+  int i, ii, j, k, nvtxs, cnvtxs, ncon, maxidx, maxwgt, avgdegree;
+  idxtype *xadj, *adjncy, *adjwgt;
+  idxtype *match, *cmap, *degrees, *perm, *tperm;
+  float *nvwgt, vbal;
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr));
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  xadj = graph->xadj;
+  nvwgt = graph->nvwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  cmap = graph->cmap;
+  match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs));
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  tperm = idxwspacemalloc(ctrl, nvtxs);
+  degrees = idxwspacemalloc(ctrl, nvtxs);
+
+  RandomPermute(nvtxs, tperm, 1);
+  avgdegree = 0.7*(xadj[nvtxs]/nvtxs);
+  for (i=0; i<nvtxs; i++) 
+    degrees[i] = (xadj[i+1]-xadj[i] > avgdegree ? avgdegree : xadj[i+1]-xadj[i]);
+  BucketSortKeysInc(nvtxs, avgdegree, degrees, tperm, perm);
+
+  cnvtxs = 0;
+
+  /* Take care any islands. Islands are matched with non-islands due to coarsening */
+  for (ii=0; ii<nvtxs; ii++) {
+    i = perm[ii];
+
+    if (match[i] == UNMATCHED) {  /* Unmatched */
+      if (xadj[i] < xadj[i+1])
+        break;
+
+      maxidx = i;
+      for (j=nvtxs-1; j>ii; j--) {
+        k = perm[j];
+        if (match[k] == UNMATCHED && xadj[k] < xadj[k+1]) {
+          maxidx = k;
+          break;
+        }
+      }
+
+      cmap[i] = cmap[maxidx] = cnvtxs++;
+      match[i] = maxidx;
+      match[maxidx] = i;
+    }
+  }
+
+  /* Continue with normal matching */
+  for (; ii<nvtxs; ii++) {
+    i = perm[ii];
+
+    if (match[i] == UNMATCHED) {  /* Unmatched */
+      maxidx = i;
+      maxwgt = -1;
+      vbal = 0.0;
+
+      /* Find a heavy-edge matching, subject to maxvwgt constraints */
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        k = adjncy[j];
+        if (match[k] == UNMATCHED && AreAllVwgtsBelowFast(ncon, nvwgt+i*ncon, nvwgt+k*ncon, ctrl->nmaxvwgt)) {
+          if (maxidx != i)
+            vbal = BetterVBalance(ncon, norm, nvwgt+i*ncon, nvwgt+maxidx*ncon, nvwgt+k*ncon);
+
+          if (vbal > 0 || (vbal > -.01 && maxwgt < adjwgt[j])) {
+            maxwgt = adjwgt[j];
+            maxidx = k;
+          }
+        }
+      }
+
+      cmap[i] = cmap[maxidx] = cnvtxs++;
+      match[i] = maxidx;
+      match[maxidx] = i;
+    }
+  }
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr));
+
+  idxwspacefree(ctrl, nvtxs);  /* degrees */
+  idxwspacefree(ctrl, nvtxs);  /* tperm */
+
+  CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm);
+
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+
+
+
+/*************************************************************************
+* This function checks if v+u2 provides a better balance in the weight 
+* vector that v+u1
+**************************************************************************/
+float BetterVBalance(int ncon, int norm, float *vwgt, float *u1wgt, float *u2wgt)
+{
+  int i;
+  float sum1, sum2, max1, max2, min1, min2, diff1, diff2;
+
+  if (norm == -1) {
+    max1 = min1 = vwgt[0]+u1wgt[0];
+    max2 = min2 = vwgt[0]+u2wgt[0];
+    sum1 = vwgt[0]+u1wgt[0];
+    sum2 = vwgt[0]+u2wgt[0];
+
+    for (i=1; i<ncon; i++) {
+      if (max1 < vwgt[i]+u1wgt[i])
+        max1 = vwgt[i]+u1wgt[i];
+      if (min1 > vwgt[i]+u1wgt[i])
+        min1 = vwgt[i]+u1wgt[i];
+
+      if (max2 < vwgt[i]+u2wgt[i])
+        max2 = vwgt[i]+u2wgt[i];
+      if (min2 > vwgt[i]+u2wgt[i])
+        min2 = vwgt[i]+u2wgt[i];
+
+      sum1 += vwgt[i]+u1wgt[i];
+      sum2 += vwgt[i]+u2wgt[i];
+    }
+
+    if (sum1 == 0.0)
+      return 1;
+    else if (sum2 == 0.0)
+      return -1;
+    else
+      return ((max1-min1)/sum1) - ((max2-min2)/sum2);
+  }
+  else if (norm == 1) {
+    sum1 = sum2 = 0.0;
+    for (i=0; i<ncon; i++) {
+      sum1 += vwgt[i]+u1wgt[i];
+      sum2 += vwgt[i]+u2wgt[i];
+    }
+    sum1 = sum1/(1.0*ncon);
+    sum2 = sum2/(1.0*ncon);
+
+    diff1 = diff2 = 0.0;
+    for (i=0; i<ncon; i++) {
+      diff1 += fabs(sum1 - (vwgt[i]+u1wgt[i]));
+      diff2 += fabs(sum2 - (vwgt[i]+u2wgt[i]));
+    }
+
+    return diff1 - diff2;
+  }
+  else {
+    errexit("Unknown norm: %d\n", norm);
+  }
+  return 0.0;
+}
+
+
+/*************************************************************************
+* This function checks if the vertex weights of two vertices are below 
+* a given set of values
+**************************************************************************/
+int AreAllVwgtsBelowFast(int ncon, float *vwgt1, float *vwgt2, float limit)
+{
+  int i;
+
+  for (i=0; i<ncon; i++)
+    if (vwgt1[i] + vwgt2[i] > limit)
+      return 0;
+
+  return 1;
+}
+
diff --git a/Metis/mmd.c b/Metis/mmd.c
new file mode 100644
index 0000000000..bf3d16d786
--- /dev/null
+++ b/Metis/mmd.c
@@ -0,0 +1,593 @@
+/*
+ * mmd.c
+ *
+ * **************************************************************
+ * The following C function was developed from a FORTRAN subroutine
+ * in SPARSPAK written by Eleanor Chu, Alan George, Joseph Liu
+ * and Esmond Ng.
+ * 
+ * The FORTRAN-to-C transformation and modifications such as dynamic
+ * memory allocation and deallocation were performed by Chunguang
+ * Sun.
+ * ************************************************************** 
+ *
+ * Taken from SMMS, George 12/13/94
+ *
+ * The meaning of invperm, and perm vectors is different from that
+ * in genqmd_ of SparsPak
+ *
+ * $Id: mmd.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+*  genmmd  -- multiple minimum external degree
+*  purpose -- this routine implements the minimum degree
+*     algorithm. it makes use of the implicit representation
+*     of elimination graphs by quotient graphs, and the notion
+*     of indistinguishable nodes. It also implements the modifications
+*     by multiple elimination and minimum external degree.
+*     Caution -- the adjacency vector adjncy will be destroyed.
+*  Input parameters --
+*     neqns -- number of equations.
+*     (xadj, adjncy) -- the adjacency structure.
+*     delta  -- tolerance value for multiple elimination.
+*     maxint -- maximum machine representable (short) integer
+*               (any smaller estimate will do) for marking nodes.
+*  Output parameters --
+*     perm -- the minimum degree ordering.
+*     invp -- the inverse of perm.
+*     *ncsub -- an upper bound on the number of nonzero subscripts
+*               for the compressed storage scheme.
+*  Working parameters --
+*     head -- vector for head of degree lists.
+*     invp  -- used temporarily for degree forward link.
+*     perm  -- used temporarily for degree backward link.
+*     qsize -- vector for size of supernodes.
+*     list -- vector for temporary linked lists.
+*     marker -- a temporary marker vector.
+*  Subroutines used -- mmdelm, mmdint, mmdnum, mmdupd.
+**************************************************************************/
+void genmmd(int neqns, idxtype *xadj, idxtype *adjncy, idxtype *invp, idxtype *perm,
+     int delta, idxtype *head, idxtype *qsize, idxtype *list, idxtype *marker,
+     int maxint, int *ncsub)
+{
+    int  ehead, i, mdeg, mdlmt, mdeg_node, nextmd, num, tag;
+
+    if (neqns <= 0)  
+      return;
+
+    /* Adjust from C to Fortran */
+    xadj--; adjncy--; invp--; perm--; head--; qsize--; list--; marker--;
+
+    /* initialization for the minimum degree algorithm. */
+    *ncsub = 0;
+    mmdint(neqns, xadj, adjncy, head, invp, perm, qsize, list, marker);
+
+    /*  'num' counts the number of ordered nodes plus 1. */
+    num = 1;
+
+    /* eliminate all isolated nodes. */
+    nextmd = head[1];
+    while (nextmd > 0) {
+      mdeg_node = nextmd;
+      nextmd = invp[mdeg_node];
+      marker[mdeg_node] = maxint;
+      invp[mdeg_node] = -num;
+      num = num + 1;
+    }
+
+    /* search for node of the minimum degree. 'mdeg' is the current */
+    /* minimum degree; 'tag' is used to facilitate marking nodes.   */
+    if (num > neqns) 
+      goto n1000;
+    tag = 1;
+    head[1] = 0;
+    mdeg = 2;
+
+    /* infinite loop here ! */
+    while (1) {
+      while (head[mdeg] <= 0) 
+        mdeg++;
+
+      /* use value of 'delta' to set up 'mdlmt', which governs */
+      /* when a degree update is to be performed.              */
+      mdlmt = mdeg + delta;
+      ehead = 0;
+
+n500:
+      mdeg_node = head[mdeg];
+      while (mdeg_node <= 0) {
+        mdeg++;
+
+        if (mdeg > mdlmt) 
+          goto n900;
+        mdeg_node = head[mdeg];
+      };
+
+      /*  remove 'mdeg_node' from the degree structure. */
+      nextmd = invp[mdeg_node];
+      head[mdeg] = nextmd;
+      if (nextmd > 0)  
+        perm[nextmd] = -mdeg;
+      invp[mdeg_node] = -num;
+      *ncsub += mdeg + qsize[mdeg_node] - 2;
+      if ((num+qsize[mdeg_node]) > neqns)  
+        goto n1000;
+
+      /*  eliminate 'mdeg_node' and perform quotient graph */
+      /*  transformation. reset 'tag' value if necessary.    */
+      tag++;
+      if (tag >= maxint) {
+        tag = 1;
+        for (i = 1; i <= neqns; i++)
+          if (marker[i] < maxint)  
+            marker[i] = 0;
+      };
+
+      mmdelm(mdeg_node, xadj, adjncy, head, invp, perm, qsize, list, marker, maxint, tag);
+
+      num += qsize[mdeg_node];
+      list[mdeg_node] = ehead;
+      ehead = mdeg_node;
+      if (delta >= 0) 
+        goto n500;
+
+ n900:
+      /* update degrees of the nodes involved in the  */
+      /* minimum degree nodes elimination.            */
+      if (num > neqns)  
+        goto n1000;
+      mmdupd( ehead, neqns, xadj, adjncy, delta, &mdeg, head, invp, perm, qsize, list, marker, maxint, &tag);
+    }; /* end of -- while ( 1 ) -- */
+
+n1000:
+    mmdnum( neqns, perm, invp, qsize );
+
+    /* Adjust from Fortran back to C*/
+    xadj++; adjncy++; invp++; perm++; head++; qsize++; list++; marker++;
+}
+
+
+/**************************************************************************
+*           mmdelm ...... multiple minimum degree elimination
+* Purpose -- This routine eliminates the node mdeg_node of minimum degree
+*     from the adjacency structure, which is stored in the quotient
+*     graph format. It also transforms the quotient graph representation
+*     of the elimination graph.
+* Input parameters --
+*     mdeg_node -- node of minimum degree.
+*     maxint -- estimate of maximum representable (short) integer.
+*     tag    -- tag value.
+* Updated parameters --
+*     (xadj, adjncy) -- updated adjacency structure.
+*     (head, forward, backward) -- degree doubly linked structure.
+*     qsize -- size of supernode.
+*     marker -- marker vector.
+*     list -- temporary linked list of eliminated nabors.
+***************************************************************************/
+void mmdelm(int mdeg_node, idxtype *xadj, idxtype *adjncy, idxtype *head, idxtype *forward,
+     idxtype *backward, idxtype *qsize, idxtype *list, idxtype *marker, int maxint,int tag)
+{
+    int   element, i,   istop, istart, j,
+          jstop, jstart, link,
+          nabor, node, npv, nqnbrs, nxnode,
+          pvnode, rlmt, rloc, rnode, xqnbr;
+
+    /* find the reachable set of 'mdeg_node' and */
+    /* place it in the data structure.           */
+    marker[mdeg_node] = tag;
+    istart = xadj[mdeg_node];
+    istop = xadj[mdeg_node+1] - 1;
+
+    /* 'element' points to the beginning of the list of  */
+    /* eliminated nabors of 'mdeg_node', and 'rloc' gives the */
+    /* storage location for the next reachable node.   */
+    element = 0;
+    rloc = istart;
+    rlmt = istop;
+    for ( i = istart; i <= istop; i++ ) {
+        nabor = adjncy[i];
+        if ( nabor == 0 ) break;
+        if ( marker[nabor] < tag ) {
+           marker[nabor] = tag;
+           if ( forward[nabor] < 0 )  {
+              list[nabor] = element;
+              element = nabor;
+           } else {
+              adjncy[rloc] = nabor;
+              rloc++;
+           };
+        }; /* end of -- if -- */
+    }; /* end of -- for -- */
+
+  /* merge with reachable nodes from generalized elements. */
+  while ( element > 0 ) {
+      adjncy[rlmt] = -element;
+      link = element;
+
+n400:
+      jstart = xadj[link];
+      jstop = xadj[link+1] - 1;
+      for ( j = jstart; j <= jstop; j++ ) {
+          node = adjncy[j];
+          link = -node;
+          if ( node < 0 )  goto n400;
+          if ( node == 0 ) break;
+          if ((marker[node]<tag)&&(forward[node]>=0)) {
+             marker[node] = tag;
+             /*use storage from eliminated nodes if necessary.*/
+             while ( rloc >= rlmt ) {
+                   link = -adjncy[rlmt];
+                   rloc = xadj[link];
+                   rlmt = xadj[link+1] - 1;
+             };
+             adjncy[rloc] = node;
+             rloc++;
+          };
+      }; /* end of -- for ( j = jstart; -- */
+      element = list[element];
+    };  /* end of -- while ( element > 0 ) -- */
+    if ( rloc <= rlmt ) adjncy[rloc] = 0;
+    /* for each node in the reachable set, do the following. */
+    link = mdeg_node;
+
+n1100:
+    istart = xadj[link];
+    istop = xadj[link+1] - 1;
+    for ( i = istart; i <= istop; i++ ) {
+        rnode = adjncy[i];
+        link = -rnode;
+        if ( rnode < 0 ) goto n1100;
+        if ( rnode == 0 ) return;
+
+        /* 'rnode' is in the degree list structure. */
+        pvnode = backward[rnode];
+        if (( pvnode != 0 ) && ( pvnode != (-maxint) )) {
+           /* then remove 'rnode' from the structure. */
+           nxnode = forward[rnode];
+           if ( nxnode > 0 ) backward[nxnode] = pvnode;
+           if ( pvnode > 0 ) forward[pvnode] = nxnode;
+           npv = -pvnode;
+           if ( pvnode < 0 ) head[npv] = nxnode;
+        };
+
+        /* purge inactive quotient nabors of 'rnode'. */
+        jstart = xadj[rnode];
+        jstop = xadj[rnode+1] - 1;
+        xqnbr = jstart;
+        for ( j = jstart; j <= jstop; j++ ) {
+            nabor = adjncy[j];
+            if ( nabor == 0 ) break;
+            if ( marker[nabor] < tag ) {
+                adjncy[xqnbr] = nabor;
+                xqnbr++;
+            };
+        };
+
+        /* no active nabor after the purging. */
+        nqnbrs = xqnbr - jstart;
+        if ( nqnbrs <= 0 ) {
+           /* merge 'rnode' with 'mdeg_node'. */
+           qsize[mdeg_node] += qsize[rnode];
+           qsize[rnode] = 0;
+           marker[rnode] = maxint;
+           forward[rnode] = -mdeg_node;
+           backward[rnode] = -maxint;
+        } else {
+           /* flag 'rnode' for degree update, and  */
+           /* add 'mdeg_node' as a nabor of 'rnode'.      */
+           forward[rnode] = nqnbrs + 1;
+           backward[rnode] = 0;
+           adjncy[xqnbr] = mdeg_node;
+           xqnbr++;
+           if ( xqnbr <= jstop )  adjncy[xqnbr] = 0;
+        };
+      }; /* end of -- for ( i = istart; -- */
+      return;
+ }
+
+/***************************************************************************
+*    mmdint ---- mult minimum degree initialization
+*    purpose -- this routine performs initialization for the
+*       multiple elimination version of the minimum degree algorithm.
+*    input parameters --
+*       neqns  -- number of equations.
+*       (xadj, adjncy) -- adjacency structure.
+*    output parameters --
+*       (head, dfrow, backward) -- degree doubly linked structure.
+*       qsize -- size of supernode ( initialized to one).
+*       list -- linked list.
+*       marker -- marker vector.
+****************************************************************************/
+int  mmdint(int neqns, idxtype *xadj, idxtype *adjncy, idxtype *head, idxtype *forward,
+     idxtype *backward, idxtype *qsize, idxtype *list, idxtype *marker)
+{
+    int  fnode, ndeg, node;
+
+    for ( node = 1; node <= neqns; node++ ) {
+        head[node] = 0;
+        qsize[node] = 1;
+        marker[node] = 0;
+        list[node] = 0;
+    };
+
+    /* initialize the degree doubly linked lists. */
+    for ( node = 1; node <= neqns; node++ ) {
+        ndeg = xadj[node+1] - xadj[node]/* + 1*/;   /* george */
+        if (ndeg == 0)
+          ndeg = 1;
+        fnode = head[ndeg];
+        forward[node] = fnode;
+        head[ndeg] = node;
+        if ( fnode > 0 ) backward[fnode] = node;
+        backward[node] = -ndeg;
+    };
+    return 0;
+}
+
+/****************************************************************************
+* mmdnum --- multi minimum degree numbering
+* purpose -- this routine performs the final step in producing
+*    the permutation and inverse permutation vectors in the
+*    multiple elimination version of the minimum degree
+*    ordering algorithm.
+* input parameters --
+*     neqns -- number of equations.
+*     qsize -- size of supernodes at elimination.
+* updated parameters --
+*     invp -- inverse permutation vector. on input,
+*             if qsize[node] = 0, then node has been merged
+*             into the node -invp[node]; otherwise,
+*            -invp[node] is its inverse labelling.
+* output parameters --
+*     perm -- the permutation vector.
+****************************************************************************/
+void mmdnum(int neqns, idxtype *perm, idxtype *invp, idxtype *qsize)
+{
+  int father, nextf, node, nqsize, num, root;
+
+  for ( node = 1; node <= neqns; node++ ) {
+      nqsize = qsize[node];
+      if ( nqsize <= 0 ) perm[node] = invp[node];
+      if ( nqsize > 0 )  perm[node] = -invp[node];
+  };
+
+  /* for each node which has been merged, do the following. */
+  for ( node = 1; node <= neqns; node++ ) {
+      if ( perm[node] <= 0 )  {
+
+	 /* trace the merged tree until one which has not */
+         /* been merged, call it root.                    */
+         father = node;
+         while ( perm[father] <= 0 )
+            father = - perm[father];
+
+         /* number node after root. */
+         root = father;
+         num = perm[root] + 1;
+         invp[node] = -num;
+         perm[root] = num;
+
+         /* shorten the merged tree. */
+         father = node;
+         nextf = - perm[father];
+         while ( nextf > 0 ) {
+            perm[father] = -root;
+            father = nextf;
+            nextf = -perm[father];
+         };
+      };  /* end of -- if ( perm[node] <= 0 ) -- */
+  }; /* end of -- for ( node = 1; -- */
+
+  /* ready to compute perm. */
+  for ( node = 1; node <= neqns; node++ ) {
+        num = -invp[node];
+        invp[node] = num;
+        perm[num] = node;
+  };
+  return;
+}
+
+/****************************************************************************
+* mmdupd ---- multiple minimum degree update
+* purpose -- this routine updates the degrees of nodes after a
+*            multiple elimination step.
+* input parameters --
+*    ehead -- the beginning of the list of eliminated nodes
+*             (i.e., newly formed elements).
+*    neqns -- number of equations.
+*    (xadj, adjncy) -- adjacency structure.
+*    delta -- tolerance value for multiple elimination.
+*    maxint -- maximum machine representable (short) integer.
+* updated parameters --
+*    mdeg -- new minimum degree after degree update.
+*    (head, forward, backward) -- degree doubly linked structure.
+*    qsize -- size of supernode.
+*    list -- marker vector for degree update.
+*    *tag   -- tag value.
+****************************************************************************/
+void mmdupd(int ehead, int neqns, idxtype *xadj, idxtype *adjncy, int delta, int *mdeg,
+     idxtype *head, idxtype *forward, idxtype *backward, idxtype *qsize, idxtype *list,
+     idxtype *marker, int maxint,int *tag)
+{
+ int  deg, deg0, element, enode, fnode, i, iq2, istop,
+      istart, j, jstop, jstart, link, mdeg0, mtag, nabor,
+      node, q2head, qxhead;
+
+      mdeg0 = *mdeg + delta;
+      element = ehead;
+
+n100:
+      if ( element <= 0 ) return;
+
+      /* for each of the newly formed element, do the following. */
+      /* reset tag value if necessary.                           */
+      mtag = *tag + mdeg0;
+      if ( mtag >= maxint ) {
+         *tag = 1;
+         for ( i = 1; i <= neqns; i++ )
+             if ( marker[i] < maxint ) marker[i] = 0;
+         mtag = *tag + mdeg0;
+      };
+
+      /* create two linked lists from nodes associated with 'element': */
+      /* one with two nabors (q2head) in the adjacency structure, and the*/
+      /* other with more than two nabors (qxhead). also compute 'deg0',*/
+      /* number of nodes in this element.                              */
+      q2head = 0;
+      qxhead = 0;
+      deg0 = 0;
+      link =element;
+
+n400:
+      istart = xadj[link];
+      istop = xadj[link+1] - 1;
+      for ( i = istart; i <= istop; i++ ) {
+          enode = adjncy[i];
+          link = -enode;
+          if ( enode < 0 )  goto n400;
+          if ( enode == 0 ) break;
+          if ( qsize[enode] != 0 ) {
+             deg0 += qsize[enode];
+             marker[enode] = mtag;
+
+             /*'enode' requires a degree update*/
+             if ( backward[enode] == 0 ) {
+                /* place either in qxhead or q2head list. */
+                if ( forward[enode] != 2 ) {
+                     list[enode] = qxhead;
+                     qxhead = enode;
+                } else {
+                     list[enode] = q2head;
+                     q2head = enode;
+                };
+             };
+          }; /* enf of -- if ( qsize[enode] != 0 ) -- */
+      }; /* end of -- for ( i = istart; -- */
+
+      /* for each node in q2 list, do the following. */
+      enode = q2head;
+      iq2 = 1;
+
+n900:
+      if ( enode <= 0 ) goto n1500;
+      if ( backward[enode] != 0 ) goto n2200;
+      (*tag)++;
+      deg = deg0;
+
+      /* identify the other adjacent element nabor. */
+      istart = xadj[enode];
+      nabor = adjncy[istart];
+      if ( nabor == element ) nabor = adjncy[istart+1];
+      link = nabor;
+      if ( forward[nabor] >= 0 ) {
+           /* nabor is uneliminated, increase degree count. */
+           deg += qsize[nabor];
+           goto n2100;
+      };
+
+       /* the nabor is eliminated. for each node in the 2nd element */
+       /* do the following.                                         */
+n1000:
+       istart = xadj[link];
+       istop = xadj[link+1] - 1;
+       for ( i = istart; i <= istop; i++ ) {
+           node = adjncy[i];
+           link = -node;
+           if ( node != enode ) {
+                if ( node < 0 ) goto n1000;
+                if ( node == 0 )  goto n2100;
+                if ( qsize[node] != 0 ) {
+                     if ( marker[node] < *tag ) {
+                        /* 'node' is not yet considered. */
+                        marker[node] = *tag;
+                        deg += qsize[node];
+                     } else {
+                        if ( backward[node] == 0 ) {
+                             if ( forward[node] == 2 ) {
+                                /* 'node' is indistinguishable from 'enode'.*/
+                                /* merge them into a new supernode.         */
+                                qsize[enode] += qsize[node];
+                                qsize[node] = 0;
+                                marker[node] = maxint;
+                                forward[node] = -enode;
+                                backward[node] = -maxint;
+                             } else {
+                                /* 'node' is outmacthed by 'enode' */
+				if (backward[node]==0) backward[node] = -maxint;
+                             };
+                        }; /* end of -- if ( backward[node] == 0 ) -- */
+                    }; /* end of -- if ( marker[node] < *tag ) -- */
+                }; /* end of -- if ( qsize[node] != 0 ) -- */
+              }; /* end of -- if ( node != enode ) -- */
+          }; /* end of -- for ( i = istart; -- */
+          goto n2100;
+
+n1500:
+          /* for each 'enode' in the 'qx' list, do the following. */
+          enode = qxhead;
+          iq2 = 0;
+
+n1600:    if ( enode <= 0 )  goto n2300;
+          if ( backward[enode] != 0 )  goto n2200;
+          (*tag)++;
+          deg = deg0;
+
+          /*for each unmarked nabor of 'enode', do the following.*/
+          istart = xadj[enode];
+          istop = xadj[enode+1] - 1;
+          for ( i = istart; i <= istop; i++ ) {
+                nabor = adjncy[i];
+                if ( nabor == 0 ) break;
+                if ( marker[nabor] < *tag ) {
+                     marker[nabor] = *tag;
+                     link = nabor;
+                     if ( forward[nabor] >= 0 ) 
+                          /*if uneliminated, include it in deg count.*/
+                          deg += qsize[nabor];
+                     else {
+n1700:
+                          /* if eliminated, include unmarked nodes in this*/
+                          /* element into the degree count.             */
+                          jstart = xadj[link];
+                          jstop = xadj[link+1] - 1;
+                          for ( j = jstart; j <= jstop; j++ ) {
+                                node = adjncy[j];
+                                link = -node;
+                                if ( node < 0 ) goto n1700;
+                                if ( node == 0 ) break;
+                                if ( marker[node] < *tag ) {
+                                    marker[node] = *tag;
+                                    deg += qsize[node];
+                                };
+                          }; /* end of -- for ( j = jstart; -- */
+                     }; /* end of -- if ( forward[nabor] >= 0 ) -- */
+                  }; /* end of -- if ( marker[nabor] < *tag ) -- */
+          }; /* end of -- for ( i = istart; -- */
+
+n2100:
+          /* update external degree of 'enode' in degree structure, */
+          /* and '*mdeg' if necessary.                     */
+          deg = deg - qsize[enode] + 1;
+          fnode = head[deg];
+          forward[enode] = fnode;
+          backward[enode] = -deg;
+          if ( fnode > 0 ) backward[fnode] = enode;
+          head[deg] = enode;
+          if ( deg < *mdeg ) *mdeg = deg;
+
+n2200:
+          /* get next enode in current element. */
+          enode = list[enode];
+          if ( iq2 == 1 ) goto n900;
+          goto n1600;
+
+n2300:
+          /* get next element in the list. */
+          *tag = mtag;
+          element = list[element];
+          goto n100;
+    }
diff --git a/Metis/mpmetis.c b/Metis/mpmetis.c
new file mode 100644
index 0000000000..e8795cafdc
--- /dev/null
+++ b/Metis/mpmetis.c
@@ -0,0 +1,402 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * mpmetis.c
+ *
+ * This file contains the top level routines for the multilevel recursive
+ * bisection algorithm PMETIS.
+ *
+ * Started 7/24/97
+ * George
+ *
+ * $Id: mpmetis.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+
+/*************************************************************************
+* This function is the entry point for PWMETIS that accepts exact weights
+* for the target partitions
+**************************************************************************/
+void METIS_mCPartGraphRecursive(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, 
+       idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, 
+       int *options, int *edgecut, idxtype *part)
+{
+  int i, j;
+  GraphType graph;
+  CtrlType ctrl;
+
+  if (*numflag == 1)
+    Change2CNumbering(*nvtxs, xadj, adjncy);
+
+  SetUpGraph(&graph, OP_PMETIS, *nvtxs, *ncon, xadj, adjncy, vwgt, adjwgt, *wgtflag);
+
+  if (options[0] == 0) {  /* Use the default parameters */
+    ctrl.CType  = McPMETIS_CTYPE;
+    ctrl.IType  = McPMETIS_ITYPE;
+    ctrl.RType  = McPMETIS_RTYPE;
+    ctrl.dbglvl = McPMETIS_DBGLVL;
+  }
+  else {
+    ctrl.CType  = options[OPTION_CTYPE];
+    ctrl.IType  = options[OPTION_ITYPE];
+    ctrl.RType  = options[OPTION_RTYPE];
+    ctrl.dbglvl = options[OPTION_DBGLVL];
+  }
+  ctrl.optype = OP_PMETIS;
+  ctrl.CoarsenTo = 100;
+
+  ctrl.nmaxvwgt = 1.5/(1.0*ctrl.CoarsenTo);
+
+  InitRandom(-1);
+
+  AllocateWorkSpace(&ctrl, &graph, *nparts);
+
+  IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl));
+  IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr));
+
+  *edgecut = MCMlevelRecursiveBisection(&ctrl, &graph, *nparts, part, 1.000, 0);
+
+  IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr));
+  IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl));
+
+  FreeWorkSpace(&ctrl, &graph);
+
+  if (*numflag == 1)
+    Change2FNumbering(*nvtxs, xadj, adjncy, part);
+}
+
+
+
+/*************************************************************************
+* This function is the entry point for PWMETIS that accepts exact weights
+* for the target partitions
+**************************************************************************/
+void METIS_mCHPartGraphRecursive(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, 
+       idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, 
+       float *ubvec, int *options, int *edgecut, idxtype *part)
+{
+  int i, j;
+  GraphType graph;
+  CtrlType ctrl;
+  float *myubvec;
+
+  if (*numflag == 1)
+    Change2CNumbering(*nvtxs, xadj, adjncy);
+
+  SetUpGraph(&graph, OP_PMETIS, *nvtxs, *ncon, xadj, adjncy, vwgt, adjwgt, *wgtflag);
+
+  if (options[0] == 0) {  /* Use the default parameters */
+    ctrl.CType = PMETIS_CTYPE;
+    ctrl.IType = PMETIS_ITYPE;
+    ctrl.RType = PMETIS_RTYPE;
+    ctrl.dbglvl = PMETIS_DBGLVL;
+  }
+  else {
+    ctrl.CType = options[OPTION_CTYPE];
+    ctrl.IType = options[OPTION_ITYPE];
+    ctrl.RType = options[OPTION_RTYPE];
+    ctrl.dbglvl = options[OPTION_DBGLVL];
+  }
+  ctrl.optype = OP_PMETIS;
+  ctrl.CoarsenTo = 100;
+
+  ctrl.nmaxvwgt = 1.5/(1.0*ctrl.CoarsenTo);
+
+  myubvec = fmalloc(*ncon, "PWMETIS: mytpwgts");
+  scopy(*ncon, ubvec, myubvec);
+
+  InitRandom(-1);
+
+  AllocateWorkSpace(&ctrl, &graph, *nparts);
+
+  IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl));
+  IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr));
+
+  *edgecut = MCHMlevelRecursiveBisection(&ctrl, &graph, *nparts, part, myubvec, 0);
+
+  IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr));
+  IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl));
+
+  FreeWorkSpace(&ctrl, &graph);
+  GKfree(&myubvec, LTERM);
+
+  if (*numflag == 1)
+    Change2FNumbering(*nvtxs, xadj, adjncy, part);
+}
+
+
+
+/*************************************************************************
+* This function is the entry point for PWMETIS that accepts exact weights
+* for the target partitions
+**************************************************************************/
+void METIS_mCPartGraphRecursiveInternal(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, 
+       float *nvwgt, idxtype *adjwgt, int *nparts, int *options, int *edgecut, idxtype *part)
+{
+  int i, j;
+  GraphType graph;
+  CtrlType ctrl;
+
+  SetUpGraph2(&graph, *nvtxs, *ncon, xadj, adjncy, nvwgt, adjwgt);
+
+  if (options[0] == 0) {  /* Use the default parameters */
+    ctrl.CType = PMETIS_CTYPE;
+    ctrl.IType = PMETIS_ITYPE;
+    ctrl.RType = PMETIS_RTYPE;
+    ctrl.dbglvl = PMETIS_DBGLVL;
+  }
+  else {
+    ctrl.CType = options[OPTION_CTYPE];
+    ctrl.IType = options[OPTION_ITYPE];
+    ctrl.RType = options[OPTION_RTYPE];
+    ctrl.dbglvl = options[OPTION_DBGLVL];
+  }
+  ctrl.optype = OP_PMETIS;
+  ctrl.CoarsenTo = 100;
+
+  ctrl.nmaxvwgt = 1.5/(1.0*ctrl.CoarsenTo);
+
+  InitRandom(-1);
+
+  AllocateWorkSpace(&ctrl, &graph, *nparts);
+
+  IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl));
+  IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr));
+
+  *edgecut = MCMlevelRecursiveBisection(&ctrl, &graph, *nparts, part, 1.000, 0);
+
+  IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr));
+  IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl));
+
+  FreeWorkSpace(&ctrl, &graph);
+
+}
+
+
+/*************************************************************************
+* This function is the entry point for PWMETIS that accepts exact weights
+* for the target partitions
+**************************************************************************/
+void METIS_mCHPartGraphRecursiveInternal(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, 
+       float *nvwgt, idxtype *adjwgt, int *nparts, float *ubvec, int *options, int *edgecut, 
+       idxtype *part)
+{
+  int i, j;
+  GraphType graph;
+  CtrlType ctrl;
+  float *myubvec;
+
+  SetUpGraph2(&graph, *nvtxs, *ncon, xadj, adjncy, nvwgt, adjwgt);
+
+  if (options[0] == 0) {  /* Use the default parameters */
+    ctrl.CType = PMETIS_CTYPE;
+    ctrl.IType = PMETIS_ITYPE;
+    ctrl.RType = PMETIS_RTYPE;
+    ctrl.dbglvl = PMETIS_DBGLVL;
+  }
+  else {
+    ctrl.CType = options[OPTION_CTYPE];
+    ctrl.IType = options[OPTION_ITYPE];
+    ctrl.RType = options[OPTION_RTYPE];
+    ctrl.dbglvl = options[OPTION_DBGLVL];
+  }
+  ctrl.optype = OP_PMETIS;
+  ctrl.CoarsenTo = 100;
+
+  ctrl.nmaxvwgt = 1.5/(1.0*ctrl.CoarsenTo);
+
+  myubvec = fmalloc(*ncon, "PWMETIS: mytpwgts");
+  scopy(*ncon, ubvec, myubvec);
+
+  InitRandom(-1);
+
+  AllocateWorkSpace(&ctrl, &graph, *nparts);
+
+  IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl));
+  IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr));
+
+  *edgecut = MCHMlevelRecursiveBisection(&ctrl, &graph, *nparts, part, myubvec, 0);
+
+  IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr));
+  IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl));
+
+  FreeWorkSpace(&ctrl, &graph);
+  GKfree(&myubvec, LTERM);
+
+}
+
+
+
+
+/*************************************************************************
+* This function takes a graph and produces a bisection of it
+**************************************************************************/
+int MCMlevelRecursiveBisection(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, 
+       float ubfactor, int fpart)
+{
+  int i, j, nvtxs, ncon, cut;
+  idxtype *label, *where;
+  GraphType lgraph, rgraph;
+  float tpwgts[2];
+
+  nvtxs = graph->nvtxs;
+  if (nvtxs == 0) {
+    printf("\t***Cannot bisect a graph with 0 vertices!\n\t***You are trying to partition a graph into too many parts!\n");
+    return 0;
+  }
+
+  /* Determine the weights of the partitions */
+  tpwgts[0] = 1.0*(nparts>>1)/(1.0*nparts);
+  tpwgts[1] = 1.0 - tpwgts[0];
+
+  MCMlevelEdgeBisection(ctrl, graph, tpwgts, ubfactor);
+  cut = graph->mincut;
+
+  label = graph->label;
+  where = graph->where;
+  for (i=0; i<nvtxs; i++)
+    part[label[i]] = where[i] + fpart;
+
+  if (nparts > 2) 
+    SplitGraphPart(ctrl, graph, &lgraph, &rgraph);
+
+  /* Free the memory of the top level graph */
+  GKfree(&graph->gdata, &graph->nvwgt, &graph->rdata, &graph->npwgts, &graph->label, LTERM);
+
+
+  /* Do the recursive call */
+  if (nparts > 3) {
+    cut += MCMlevelRecursiveBisection(ctrl, &lgraph, nparts/2, part, ubfactor, fpart);
+    cut += MCMlevelRecursiveBisection(ctrl, &rgraph, nparts-nparts/2, part, ubfactor, fpart+nparts/2);
+  }
+  else if (nparts == 3) {
+    cut += MCMlevelRecursiveBisection(ctrl, &rgraph, nparts-nparts/2, part, ubfactor, fpart+nparts/2);
+    GKfree(&lgraph.gdata, &lgraph.nvwgt, &lgraph.label, LTERM);
+  }
+
+  return cut;
+
+}
+
+
+
+/*************************************************************************
+* This function takes a graph and produces a bisection of it
+**************************************************************************/
+int MCHMlevelRecursiveBisection(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, 
+      float *ubvec, int fpart)
+{
+  int i, j, nvtxs, ncon, cut;
+  idxtype *label, *where;
+  GraphType lgraph, rgraph;
+  float tpwgts[2], *npwgts, *lubvec, *rubvec;
+
+  lubvec = rubvec = NULL;
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  if (nvtxs == 0) {
+    printf("\t***Cannot bisect a graph with 0 vertices!\n\t***You are trying to partition a graph into too many parts!\n");
+    return 0;
+  }
+
+  /* Determine the weights of the partitions */
+  tpwgts[0] = 1.0*(nparts>>1)/(1.0*nparts);
+  tpwgts[1] = 1.0 - tpwgts[0];
+
+  /* For now, relax at the coarsest level only */
+  if (nparts == 2)
+    MCHMlevelEdgeBisection(ctrl, graph, tpwgts, ubvec);
+  else
+    MCMlevelEdgeBisection(ctrl, graph, tpwgts, 1.000);
+  cut = graph->mincut;
+
+  label = graph->label;
+  where = graph->where;
+  for (i=0; i<nvtxs; i++)
+    part[label[i]] = where[i] + fpart;
+
+  if (nparts > 2) {
+    /* Adjust the ubvecs before the split */
+    npwgts = graph->npwgts;
+    lubvec = fmalloc(ncon, "MCHMlevelRecursiveBisection");
+    rubvec = fmalloc(ncon, "MCHMlevelRecursiveBisection");
+
+    for (i=0; i<ncon; i++) {
+      lubvec[i] = ubvec[i]*tpwgts[0]/npwgts[i];
+      lubvec[i] = amax(lubvec[i], 1.01);
+
+      rubvec[i] = ubvec[i]*tpwgts[1]/npwgts[ncon+i];
+      rubvec[i] = amax(rubvec[i], 1.01);
+    }
+
+    SplitGraphPart(ctrl, graph, &lgraph, &rgraph);
+  }
+
+  /* Free the memory of the top level graph */
+  GKfree(&graph->gdata, &graph->nvwgt, &graph->rdata, &graph->npwgts, &graph->label, LTERM);
+
+
+  /* Do the recursive call */
+  if (nparts > 3) {
+    cut += MCHMlevelRecursiveBisection(ctrl, &lgraph, nparts/2, part, lubvec, fpart);
+    cut += MCHMlevelRecursiveBisection(ctrl, &rgraph, nparts-nparts/2, part, rubvec, fpart+nparts/2);
+  }
+  else if (nparts == 3) {
+    cut += MCHMlevelRecursiveBisection(ctrl, &rgraph, nparts-nparts/2, part, rubvec, fpart+nparts/2);
+    GKfree(&lgraph.gdata, &lgraph.nvwgt, &lgraph.label, LTERM);
+  }
+
+  GKfree(&lubvec, &rubvec, LTERM);
+
+  return cut;
+
+}
+
+
+
+
+/*************************************************************************
+* This function performs multilevel bisection
+**************************************************************************/
+void MCMlevelEdgeBisection(CtrlType *ctrl, GraphType *graph, float *tpwgts, float ubfactor)
+{
+  GraphType *cgraph;
+
+  cgraph = MCCoarsen2Way(ctrl, graph);
+
+  MocInit2WayPartition(ctrl, cgraph, tpwgts, ubfactor);
+
+  MocRefine2Way(ctrl, graph, cgraph, tpwgts, ubfactor); 
+
+}
+
+
+
+/*************************************************************************
+* This function performs multilevel bisection
+**************************************************************************/
+void MCHMlevelEdgeBisection(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec)
+{
+  int i;
+  GraphType *cgraph;
+
+/*
+  for (i=0; i<graph->ncon; i++)
+    printf("%.4f ", ubvec[i]);
+  printf("\n");
+*/
+
+  cgraph = MCCoarsen2Way(ctrl, graph);
+
+  MocInit2WayPartition2(ctrl, cgraph, tpwgts, ubvec);
+
+  MocRefine2Way2(ctrl, graph, cgraph, tpwgts, ubvec); 
+
+}
+
+
diff --git a/Metis/mrefine.c b/Metis/mrefine.c
new file mode 100644
index 0000000000..1012311581
--- /dev/null
+++ b/Metis/mrefine.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * refine.c
+ *
+ * This file contains the driving routines for multilevel refinement
+ *
+ * Started 7/24/97
+ * George
+ *
+ * $Id: mrefine.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function is the entry point of refinement
+**************************************************************************/
+void MocRefine2Way(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, float *tpwgts, float ubfactor)
+{
+  int i;
+  float tubvec[MAXNCON];
+
+  for (i=0; i<graph->ncon; i++)
+    tubvec[i] = 1.0;
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr));
+
+  /* Compute the parameters of the coarsest graph */
+  MocCompute2WayPartitionParams(ctrl, graph);
+
+  for (;;) {
+    ASSERT(CheckBnd(graph));
+
+    IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr));
+    switch (ctrl->RType) {
+      case RTYPE_FM:
+        MocBalance2Way(ctrl, graph, tpwgts, 1.03);
+        MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 8); 
+        break;
+      case 2:
+        MocBalance2Way(ctrl, graph, tpwgts, 1.03);
+        MocFM_2WayEdgeRefine2(ctrl, graph, tpwgts, tubvec, 8); 
+        break;
+      default:
+        errexit("Unknown refinement type: %d\n", ctrl->RType);
+    }
+    IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr));
+
+    if (graph == orggraph)
+      break;
+
+    graph = graph->finer;
+    IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr));
+    MocProject2WayPartition(ctrl, graph);
+    IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr));
+  }
+
+  MocBalance2Way(ctrl, graph, tpwgts, 1.01);
+  MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 8); 
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr));
+}
+
+
+/*************************************************************************
+* This function allocates memory for 2-way edge refinement
+**************************************************************************/
+void MocAllocate2WayPartitionMemory(CtrlType *ctrl, GraphType *graph)
+{
+  int nvtxs, ncon;
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+
+  graph->rdata = idxmalloc(5*nvtxs, "Allocate2WayPartitionMemory: rdata");
+  graph->where		= graph->rdata;
+  graph->id		= graph->rdata + nvtxs;
+  graph->ed		= graph->rdata + 2*nvtxs;
+  graph->bndptr		= graph->rdata + 3*nvtxs;
+  graph->bndind		= graph->rdata + 4*nvtxs;
+
+  graph->npwgts 	= fmalloc(2*ncon, "npwgts");
+}
+
+
+/*************************************************************************
+* This function computes the initial id/ed 
+**************************************************************************/
+void MocCompute2WayPartitionParams(CtrlType *ctrl, GraphType *graph)
+{
+  int i, j, k, l, nvtxs, ncon, nbnd, mincut;
+  idxtype *xadj, *adjncy, *adjwgt;
+  float *nvwgt, *npwgts;
+  idxtype *id, *ed, *where;
+  idxtype *bndptr, *bndind;
+  int me, other;
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  xadj = graph->xadj;
+  nvwgt = graph->nvwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  where = graph->where;
+  npwgts = sset(2*ncon, 0.0, graph->npwgts);
+  id = idxset(nvtxs, 0, graph->id);
+  ed = idxset(nvtxs, 0, graph->ed);
+  bndptr = idxset(nvtxs, -1, graph->bndptr);
+  bndind = graph->bndind;
+
+
+  /*------------------------------------------------------------
+  / Compute now the id/ed degrees
+  /------------------------------------------------------------*/
+  nbnd = mincut = 0;
+  for (i=0; i<nvtxs; i++) {
+    ASSERT(where[i] >= 0 && where[i] <= 1);
+    me = where[i];
+    saxpy(ncon, 1.0, nvwgt+i*ncon, 1, npwgts+me*ncon, 1);
+
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      if (me == where[adjncy[j]])
+        id[i] += adjwgt[j];
+      else
+        ed[i] += adjwgt[j];
+    }
+
+    if (ed[i] > 0 || xadj[i] == xadj[i+1]) {
+      mincut += ed[i];
+      bndptr[i] = nbnd;
+      bndind[nbnd++] = i;
+    }
+  }
+
+  graph->mincut = mincut/2;
+  graph->nbnd = nbnd;
+
+}
+
+
+
+/*************************************************************************
+* This function projects a partition, and at the same time computes the
+* parameters for refinement.
+**************************************************************************/
+void MocProject2WayPartition(CtrlType *ctrl, GraphType *graph)
+{
+  int i, j, k, nvtxs, nbnd, me;
+  idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum;
+  idxtype *cmap, *where, *id, *ed, *bndptr, *bndind;
+  idxtype *cwhere, *cid, *ced, *cbndptr;
+  GraphType *cgraph;
+
+  cgraph = graph->coarser;
+  cwhere = cgraph->where;
+  cid = cgraph->id;
+  ced = cgraph->ed;
+  cbndptr = cgraph->bndptr;
+
+  nvtxs = graph->nvtxs;
+  cmap = graph->cmap;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+  adjwgtsum = graph->adjwgtsum;
+
+  MocAllocate2WayPartitionMemory(ctrl, graph);
+
+  where = graph->where;
+  id = idxset(nvtxs, 0, graph->id);
+  ed = idxset(nvtxs, 0, graph->ed);
+  bndptr = idxset(nvtxs, -1, graph->bndptr);
+  bndind = graph->bndind;
+
+
+  /* Go through and project partition and compute id/ed for the nodes */
+  for (i=0; i<nvtxs; i++) {
+    k = cmap[i];
+    where[i] = cwhere[k];
+    cmap[i] = cbndptr[k];
+  }
+
+  for (nbnd=0, i=0; i<nvtxs; i++) {
+    me = where[i];
+
+    id[i] = adjwgtsum[i];
+
+    if (xadj[i] == xadj[i+1]) {
+      bndptr[i] = nbnd;
+      bndind[nbnd++] = i;
+    }
+    else {
+      if (cmap[i] != -1) { /* If it is an interface node. Note that cmap[i] = cbndptr[cmap[i]] */
+        for (j=xadj[i]; j<xadj[i+1]; j++) {
+          if (me != where[adjncy[j]])
+            ed[i] += adjwgt[j];
+        }
+        id[i] -= ed[i];
+
+        if (ed[i] > 0 || xadj[i] == xadj[i+1]) {
+          bndptr[i] = nbnd;
+          bndind[nbnd++] = i;
+        }
+      }
+    }
+  }
+
+  graph->mincut = cgraph->mincut;
+  graph->nbnd = nbnd;
+  scopy(2*graph->ncon, cgraph->npwgts, graph->npwgts);
+
+  FreeGraph(graph->coarser);
+  graph->coarser = NULL;
+
+}
+
diff --git a/Metis/mrefine2.c b/Metis/mrefine2.c
new file mode 100644
index 0000000000..636c9a5337
--- /dev/null
+++ b/Metis/mrefine2.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * mrefine2.c
+ *
+ * This file contains the driving routines for multilevel refinement
+ *
+ * Started 7/24/97
+ * George
+ *
+ * $Id: mrefine2.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function is the entry point of refinement
+**************************************************************************/
+void MocRefine2Way2(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, float *tpwgts, 
+       float *ubvec)
+{
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr));
+
+  /* Compute the parameters of the coarsest graph */
+  MocCompute2WayPartitionParams(ctrl, graph);
+
+  for (;;) {
+    ASSERT(CheckBnd(graph));
+
+    IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr));
+    switch (ctrl->RType) {
+      case RTYPE_FM:
+        MocBalance2Way2(ctrl, graph, tpwgts, ubvec);
+        MocFM_2WayEdgeRefine2(ctrl, graph, tpwgts, ubvec, 8); 
+        break;
+      default:
+        errexit("Unknown refinement type: %d\n", ctrl->RType);
+    }
+    IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr));
+
+    if (graph == orggraph)
+      break;
+
+    graph = graph->finer;
+    IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr));
+    MocProject2WayPartition(ctrl, graph);
+    IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr));
+  }
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr));
+}
+
+
diff --git a/Metis/mutil.c b/Metis/mutil.c
new file mode 100644
index 0000000000..08871df652
--- /dev/null
+++ b/Metis/mutil.c
@@ -0,0 +1,101 @@
+/*
+ * mutil.c 
+ *
+ * This file contains various utility functions for the MOC portion of the
+ * code
+ *
+ * Started 2/15/98
+ * George
+ *
+ * $Id: mutil.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function checks if the vertex weights of two vertices are below 
+* a given set of values
+**************************************************************************/
+int AreAllVwgtsBelow(int ncon, float alpha, float *vwgt1, float beta, float *vwgt2, float limit)
+{
+  int i;
+
+  for (i=0; i<ncon; i++)
+    if (alpha*vwgt1[i] + beta*vwgt2[i] > limit)
+      return 0;
+
+  return 1;
+}
+
+
+/*************************************************************************
+* This function checks if the vertex weights of two vertices are below 
+* a given set of values
+**************************************************************************/
+int AreAnyVwgtsBelow(int ncon, float alpha, float *vwgt1, float beta, float *vwgt2, float limit)
+{
+  int i;
+
+  for (i=0; i<ncon; i++)
+    if (alpha*vwgt1[i] + beta*vwgt2[i] < limit)
+      return 1;
+
+  return 0;
+}
+
+
+
+/*************************************************************************
+* This function checks if the vertex weights of two vertices are above 
+* a given set of values
+**************************************************************************/
+int AreAllVwgtsAbove(int ncon, float alpha, float *vwgt1, float beta, float *vwgt2, float limit)
+{
+  int i;
+
+  for (i=0; i<ncon; i++)
+    if (alpha*vwgt1[i] + beta*vwgt2[i] < limit)
+      return 0;
+
+  return 1;
+}
+
+
+/*************************************************************************
+* This function computes the load imbalance over all the constrains
+* For now assume that we just want balanced partitionings
+**************************************************************************/ 
+float ComputeLoadImbalance(int ncon, int nparts, float *npwgts, float *tpwgts)
+{
+  int i, j;
+  float max, lb=0.0;
+
+  for (i=0; i<ncon; i++) {
+    max = 0.0;
+    for (j=0; j<nparts; j++) {
+      if (npwgts[j*ncon+i] > max)
+        max = npwgts[j*ncon+i];
+    }
+    if (max*nparts > lb)
+      lb = max*nparts;
+  }
+
+  return lb;
+}
+
+/*************************************************************************
+* This function checks if the vertex weights of two vertices are below 
+* a given set of values
+**************************************************************************/
+int AreAllBelow(int ncon, float *v1, float *v2)
+{
+  int i;
+
+  for (i=0; i<ncon; i++)
+    if (v1[i] > v2[i])
+      return 0;
+
+  return 1;
+}
diff --git a/Metis/myqsort.c b/Metis/myqsort.c
new file mode 100644
index 0000000000..07267ae34a
--- /dev/null
+++ b/Metis/myqsort.c
@@ -0,0 +1,547 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * myqsort.c
+ * 
+ * This file contains a fast idxtype increasing qsort algorithm.
+ * Addopted from TeX
+ * 
+ * Started 10/18/96
+ * George
+ * 
+ * $Id: myqsort.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ */
+
+#include <metis.h>			/* only for type declarations */
+
+#define		THRESH		1	/* threshold for insertion */
+#define		MTHRESH		6	/* threshold for median */
+
+
+
+
+static void siqst(idxtype *, idxtype *);
+static void iiqst(int *, int *);
+static void keyiqst(KeyValueType *, KeyValueType *);
+static void keyvaliqst(KeyValueType *, KeyValueType *);
+
+
+/*************************************************************************
+* Entry point of idxtype increasing sort
+**************************************************************************/
+void iidxsort(int n, idxtype *base)
+{
+  register idxtype *i;
+  register idxtype *j;
+  register idxtype *lo;
+  register idxtype *hi;
+  register idxtype *min;
+  register idxtype c;
+  idxtype *max;
+
+  if (n <= 1)
+    return;
+
+  max = base + n;
+
+  if (n >= THRESH) {
+    siqst(base, max);
+    hi = base + THRESH;
+  }
+  else 
+    hi = max;
+
+  for (j = lo = base; lo++ < hi;) {
+    if (*j > *lo)
+      j = lo;
+  }
+  if (j != base) { /* swap j into place */
+    c = *base;
+    *base = *j;
+    *j = c;
+  }
+
+  for (min = base; (hi = min += 1) < max;) {
+    while (*(--hi) > *min);
+    if ((hi += 1) != min) {
+      for (lo = min + 1; --lo >= min;) {
+	c = *lo;
+	for (i = j = lo; (j -= 1) >= hi; i = j)
+	   *i = *j;
+	*i = c;
+      }
+    }
+  }
+}
+
+static void siqst(idxtype *base, idxtype *max)
+{
+  register idxtype *i;
+  register idxtype *j;
+  register idxtype *jj;
+  register idxtype *mid;
+  register int ii;
+  register idxtype c;
+  idxtype *tmp;
+  int lo;
+  int hi;
+
+  lo = max - base;		/* number of elements as idxtype */
+  do {
+    mid = base + ((unsigned) lo>>1);
+    if (lo >= MTHRESH) {
+      j = (*base > *mid ? base : mid);
+      tmp = max - 1;
+      if (*j > *tmp) {
+        j = (j == base ? mid : base); /* switch to first loser */
+        if (*j < *tmp)
+          j = tmp;
+      }
+
+      if (j != mid) {  /* SWAP */ 
+        c = *mid;
+        *mid = *j;
+        *j = c;
+      }
+    }
+
+    /* Semi-standard quicksort partitioning/swapping */
+    for (i = base, j = max - 1;;) {
+      while (i < mid && *i <= *mid)
+        i++;
+      while (j > mid) {
+        if (*mid <= *j) {
+          j--;
+          continue;
+        }
+        tmp = i + 1;	/* value of i after swap */
+        if (i == mid) 	/* j <-> mid, new mid is j */
+          mid = jj = j;
+        else 		/* i <-> j */
+          jj = j--;
+        goto swap;
+      }
+
+      if (i == mid) 
+	break;
+      else {		/* i <-> mid, new mid is i */
+        jj = mid;
+        tmp = mid = i;	/* value of i after swap */
+        j--;
+      }
+swap:
+      c = *i;
+      *i = *jj;
+      *jj = c;
+      i = tmp;
+    }
+
+    i = (j = mid) + 1;
+    if ((lo = j - base) <= (hi = max - i)) {
+      if (lo >= THRESH)
+        siqst(base, j);
+      base = i;
+      lo = hi;
+    }
+    else {
+      if (hi >= THRESH)
+        siqst(i, max);
+      max = j;
+    }
+  } while (lo >= THRESH);
+}
+
+
+
+
+
+/*************************************************************************
+* Entry point of int increasing sort
+**************************************************************************/
+void iintsort(int n, int *base)
+{
+  register int *i;
+  register int *j;
+  register int *lo;
+  register int *hi;
+  register int *min;
+  register int c;
+  int *max;
+
+  if (n <= 1)
+    return;
+
+  max = base + n;
+
+  if (n >= THRESH) {
+    iiqst(base, max);
+    hi = base + THRESH;
+  }
+  else 
+    hi = max;
+
+  for (j = lo = base; lo++ < hi;) {
+    if (*j > *lo)
+      j = lo;
+  }
+  if (j != base) { /* swap j into place */
+    c = *base;
+    *base = *j;
+    *j = c;
+  }
+
+  for (min = base; (hi = min += 1) < max;) {
+    while (*(--hi) > *min);
+    if ((hi += 1) != min) {
+      for (lo = min + 1; --lo >= min;) {
+	c = *lo;
+	for (i = j = lo; (j -= 1) >= hi; i = j)
+	   *i = *j;
+	*i = c;
+      }
+    }
+  }
+}
+
+
+static void iiqst(int *base, int *max)
+{
+  register int *i;
+  register int *j;
+  register int *jj;
+  register int *mid;
+  register int ii;
+  register int c;
+  int *tmp;
+  int lo;
+  int hi;
+
+  lo = max - base;		/* number of elements as ints */
+  do {
+    mid = base + ((unsigned) lo>>1);
+    if (lo >= MTHRESH) {
+      j = (*base > *mid ? base : mid);
+      tmp = max - 1;
+      if (*j > *tmp) {
+        j = (j == base ? mid : base); /* switch to first loser */
+        if (*j < *tmp)
+          j = tmp;
+      }
+
+      if (j != mid) {  /* SWAP */ 
+        c = *mid;
+        *mid = *j;
+        *j = c;
+      }
+    }
+
+    /* Semi-standard quicksort partitioning/swapping */
+    for (i = base, j = max - 1;;) {
+      while (i < mid && *i <= *mid)
+        i++;
+      while (j > mid) {
+        if (*mid <= *j) {
+          j--;
+          continue;
+        }
+        tmp = i + 1;	/* value of i after swap */
+        if (i == mid) 	/* j <-> mid, new mid is j */
+          mid = jj = j;
+        else 		/* i <-> j */
+          jj = j--;
+        goto swap;
+      }
+
+      if (i == mid) 
+	break;
+      else {		/* i <-> mid, new mid is i */
+        jj = mid;
+        tmp = mid = i;	/* value of i after swap */
+        j--;
+      }
+swap:
+      c = *i;
+      *i = *jj;
+      *jj = c;
+      i = tmp;
+    }
+
+    i = (j = mid) + 1;
+    if ((lo = j - base) <= (hi = max - i)) {
+      if (lo >= THRESH)
+        iiqst(base, j);
+      base = i;
+      lo = hi;
+    }
+    else {
+      if (hi >= THRESH)
+        iiqst(i, max);
+      max = j;
+    }
+  } while (lo >= THRESH);
+}
+
+
+
+
+
+/*************************************************************************
+* Entry point of KeyVal increasing sort, ONLY key part
+**************************************************************************/
+void ikeysort(int n, KeyValueType *base)
+{
+  register KeyValueType *i;
+  register KeyValueType *j;
+  register KeyValueType *lo;
+  register KeyValueType *hi;
+  register KeyValueType *min;
+  register KeyValueType c;
+  KeyValueType *max;
+
+  if (n <= 1)
+    return;
+
+  max = base + n;
+
+  if (n >= THRESH) {
+    keyiqst(base, max);
+    hi = base + THRESH;
+  }
+  else 
+    hi = max;
+
+  for (j = lo = base; lo++ < hi;) {
+    if (j->key > lo->key)
+      j = lo;
+  }
+  if (j != base) { /* swap j into place */
+    c = *base;
+    *base = *j;
+    *j = c;
+  }
+
+  for (min = base; (hi = min += 1) < max;) {
+    while ((--hi)->key > min->key);
+    if ((hi += 1) != min) {
+      for (lo = min + 1; --lo >= min;) {
+	c = *lo;
+	for (i = j = lo; (j -= 1) >= hi; i = j)
+	   *i = *j;
+	*i = c;
+      }
+    }
+  }
+
+  /* Sanity check */
+  { 
+    int i;
+    for (i=0; i<n-1; i++)
+      if (base[i].key > base[i+1].key)
+        printf("Something went wrong!\n");
+  }
+}
+
+
+static void keyiqst(KeyValueType *base, KeyValueType *max)
+{
+  register KeyValueType *i;
+  register KeyValueType *j;
+  register KeyValueType *jj;
+  register KeyValueType *mid;
+  register KeyValueType c;
+  KeyValueType *tmp;
+  int lo;
+  int hi;
+
+  lo = (max - base)>>1;		/* number of elements as KeyValueType */
+  do {
+    mid = base + ((unsigned) lo>>1);
+    if (lo >= MTHRESH) {
+      j = (base->key > mid->key ? base : mid);
+      tmp = max - 1;
+      if (j->key > tmp->key) {
+        j = (j == base ? mid : base); /* switch to first loser */
+        if (j->key < tmp->key)
+          j = tmp;
+      }
+
+      if (j != mid) {  /* SWAP */ 
+        c = *mid;
+        *mid = *j;
+        *j = c;
+      }
+    }
+
+    /* Semi-standard quicksort partitioning/swapping */
+    for (i = base, j = max - 1;;) {
+      while (i < mid && i->key <= mid->key)
+        i++;
+      while (j > mid) {
+        if (mid->key <= j->key) {
+          j--;
+          continue;
+        }
+        tmp = i + 1;	/* value of i after swap */
+        if (i == mid) 	/* j <-> mid, new mid is j */
+          mid = jj = j;
+        else 		/* i <-> j */
+          jj = j--;
+        goto swap;
+      }
+
+      if (i == mid) 
+	break;
+      else {		/* i <-> mid, new mid is i */
+        jj = mid;
+        tmp = mid = i;	/* value of i after swap */
+        j--;
+      }
+swap:
+      c = *i;
+      *i = *jj;
+      *jj = c;
+      i = tmp;
+    }
+
+    i = (j = mid) + 1;
+    if ((lo = (j - base)>>1) <= (hi = (max - i)>>1)) {
+      if (lo >= THRESH)
+        keyiqst(base, j);
+      base = i;
+      lo = hi;
+    }
+    else {
+      if (hi >= THRESH)
+        keyiqst(i, max);
+      max = j;
+    }
+  } while (lo >= THRESH);
+}
+
+
+
+
+/*************************************************************************
+* Entry point of KeyVal increasing sort, BOTH key and val part
+**************************************************************************/
+void ikeyvalsort(int n, KeyValueType *base)
+{
+  register KeyValueType *i;
+  register KeyValueType *j;
+  register KeyValueType *lo;
+  register KeyValueType *hi;
+  register KeyValueType *min;
+  register KeyValueType c;
+  KeyValueType *max;
+
+  if (n <= 1)
+    return;
+
+  max = base + n;
+
+  if (n >= THRESH) {
+    keyvaliqst(base, max);
+    hi = base + THRESH;
+  }
+  else 
+    hi = max;
+
+  for (j = lo = base; lo++ < hi;) {
+    if ((j->key > lo->key) || (j->key == lo->key && j->val > lo->val))
+      j = lo;
+  }
+  if (j != base) { /* swap j into place */
+    c = *base;
+    *base = *j;
+    *j = c;
+  }
+
+  for (min = base; (hi = min += 1) < max;) {
+    while ((--hi)->key > min->key || (hi->key == min->key && hi->val > min->val));
+    if ((hi += 1) != min) {
+      for (lo = min + 1; --lo >= min;) {
+	c = *lo;
+	for (i = j = lo; (j -= 1) >= hi; i = j)
+	   *i = *j;
+	*i = c;
+      }
+    }
+  }
+}
+
+
+static void keyvaliqst(KeyValueType *base, KeyValueType *max)
+{
+  register KeyValueType *i;
+  register KeyValueType *j;
+  register KeyValueType *jj;
+  register KeyValueType *mid;
+  register KeyValueType c;
+  KeyValueType *tmp;
+  int lo;
+  int hi;
+
+  lo = (max - base)>>1;		/* number of elements as KeyValueType */
+  do {
+    mid = base + ((unsigned) lo>>1);
+    if (lo >= MTHRESH) {
+      j = (base->key > mid->key || (base->key == mid->key && base->val > mid->val) ? base : mid);
+      tmp = max - 1;
+      if (j->key > tmp->key || (j->key == tmp->key && j->val > tmp->val)) {
+        j = (j == base ? mid : base); /* switch to first loser */
+        if (j->key < tmp->key || (j->key == tmp->key && j->val < tmp->val))
+          j = tmp;
+      }
+
+      if (j != mid) {  /* SWAP */ 
+        c = *mid;
+        *mid = *j;
+        *j = c;
+      }
+    }
+
+    /* Semi-standard quicksort partitioning/swapping */
+    for (i = base, j = max - 1;;) {
+      while (i < mid && (i->key < mid->key || (i->key == mid->key && i->val <= mid->val)))
+        i++;
+      while (j > mid) {
+        if (mid->key < j->key || (mid->key == j->key && mid->val <= j->val)) {
+          j--;
+          continue;
+        }
+        tmp = i + 1;	/* value of i after swap */
+        if (i == mid) 	/* j <-> mid, new mid is j */
+          mid = jj = j;
+        else 		/* i <-> j */
+          jj = j--;
+        goto swap;
+      }
+
+      if (i == mid) 
+	break;
+      else {		/* i <-> mid, new mid is i */
+        jj = mid;
+        tmp = mid = i;	/* value of i after swap */
+        j--;
+      }
+swap:
+      c = *i;
+      *i = *jj;
+      *jj = c;
+      i = tmp;
+    }
+
+    i = (j = mid) + 1;
+    if ((lo = (j - base)>>1) <= (hi = (max - i)>>1)) {
+      if (lo >= THRESH)
+        keyvaliqst(base, j);
+      base = i;
+      lo = hi;
+    }
+    else {
+      if (hi >= THRESH)
+        keyvaliqst(i, max);
+      max = j;
+    }
+  } while (lo >= THRESH);
+}
diff --git a/Metis/ometis.c b/Metis/ometis.c
new file mode 100644
index 0000000000..9ed53b4105
--- /dev/null
+++ b/Metis/ometis.c
@@ -0,0 +1,764 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * ometis.c
+ *
+ * This file contains the top level routines for the multilevel recursive
+ * bisection algorithm PMETIS.
+ *
+ * Started 7/24/97
+ * George
+ *
+ * $Id: ometis.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function is the entry point for OEMETIS
+**************************************************************************/
+void METIS_EdgeND(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, 
+                  idxtype *perm, idxtype *iperm) 
+{
+  int i, j;
+  GraphType graph;
+  CtrlType ctrl;
+
+  if (*numflag == 1)
+    Change2CNumbering(*nvtxs, xadj, adjncy);
+
+  SetUpGraph(&graph, OP_OEMETIS, *nvtxs, 1, xadj, adjncy, NULL, NULL, 0);
+
+  if (options[0] == 0) {  /* Use the default parameters */
+    ctrl.CType = OEMETIS_CTYPE;
+    ctrl.IType = OEMETIS_ITYPE;
+    ctrl.RType = OEMETIS_RTYPE;
+    ctrl.dbglvl = OEMETIS_DBGLVL;
+  }
+  else {
+    ctrl.CType = options[OPTION_CTYPE];
+    ctrl.IType = options[OPTION_ITYPE];
+    ctrl.RType = options[OPTION_RTYPE];
+    ctrl.dbglvl = options[OPTION_DBGLVL];
+  }
+  ctrl.oflags  = 0;
+  ctrl.pfactor = -1;
+  ctrl.nseps   = 1;
+
+  ctrl.optype = OP_OEMETIS;
+  ctrl.CoarsenTo = 20;
+  ctrl.maxvwgt = 1.5*(idxsum(*nvtxs, graph.vwgt)/ctrl.CoarsenTo);
+
+  InitRandom(-1);
+
+  AllocateWorkSpace(&ctrl, &graph, 2);
+
+  IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl));
+  IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr));
+
+  MlevelNestedDissection(&ctrl, &graph, iperm, ORDER_UNBALANCE_FRACTION, *nvtxs);
+
+  IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr));
+  IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl));
+
+  for (i=0; i<*nvtxs; i++)
+    perm[iperm[i]] = i;
+
+  FreeWorkSpace(&ctrl, &graph);
+
+  if (*numflag == 1)
+    Change2FNumberingOrder(*nvtxs, xadj, adjncy, perm, iperm);
+}
+
+
+/*************************************************************************
+* This function is the entry point for ONCMETIS
+**************************************************************************/
+void METIS_NodeND(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, 
+                  idxtype *perm, idxtype *iperm) 
+{
+  int i, ii, j, l, wflag, nflag;
+  GraphType graph;
+  CtrlType ctrl;
+  idxtype *cptr, *cind, *piperm;
+
+  if (*numflag == 1)
+    Change2CNumbering(*nvtxs, xadj, adjncy);
+
+  if (options[0] == 0) {  /* Use the default parameters */
+    ctrl.CType   = ONMETIS_CTYPE;
+    ctrl.IType   = ONMETIS_ITYPE;
+    ctrl.RType   = ONMETIS_RTYPE;
+    ctrl.dbglvl  = ONMETIS_DBGLVL;
+    ctrl.oflags  = ONMETIS_OFLAGS;
+    ctrl.pfactor = ONMETIS_PFACTOR;
+    ctrl.nseps   = ONMETIS_NSEPS;
+  }
+  else {
+    ctrl.CType   = options[OPTION_CTYPE];
+    ctrl.IType   = options[OPTION_ITYPE];
+    ctrl.RType   = options[OPTION_RTYPE];
+    ctrl.dbglvl  = options[OPTION_DBGLVL];
+    ctrl.oflags  = options[OPTION_OFLAGS];
+    ctrl.pfactor = options[OPTION_PFACTOR];
+    ctrl.nseps   = options[OPTION_NSEPS];
+  }
+  if (ctrl.nseps < 1)
+    ctrl.nseps = 1;
+
+  ctrl.optype = OP_ONMETIS;
+  ctrl.CoarsenTo = 100;
+
+  IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl));
+  IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr));
+
+  InitRandom(-1);
+
+  if (ctrl.pfactor > 0) { 
+    /*============================================================
+    * Prune the dense columns
+    ==============================================================*/
+    piperm = idxmalloc(*nvtxs, "ONMETIS: piperm");
+
+    PruneGraph(&ctrl, &graph, *nvtxs, xadj, adjncy, piperm, (float)(0.1*ctrl.pfactor));
+  }
+  else if (ctrl.oflags&OFLAG_COMPRESS) {
+    /*============================================================
+    * Compress the graph 
+    ==============================================================*/
+    cptr = idxmalloc(*nvtxs+1, "ONMETIS: cptr");
+    cind = idxmalloc(*nvtxs, "ONMETIS: cind");
+
+    CompressGraph(&ctrl, &graph, *nvtxs, xadj, adjncy, cptr, cind);
+
+    if (graph.nvtxs >= COMPRESSION_FRACTION*(*nvtxs)) {
+      ctrl.oflags--; /* We actually performed no compression */
+      GKfree(&cptr, &cind, LTERM);
+    }
+    else if (2*graph.nvtxs < *nvtxs && ctrl.nseps == 1)
+      ctrl.nseps = 2;
+  }
+  else {
+    SetUpGraph(&graph, OP_ONMETIS, *nvtxs, 1, xadj, adjncy, NULL, NULL, 0);
+  }
+
+
+  /*=============================================================
+  * Do the nested dissection ordering 
+  --=============================================================*/
+  ctrl.maxvwgt = 1.5*(idxsum(graph.nvtxs, graph.vwgt)/ctrl.CoarsenTo);
+  AllocateWorkSpace(&ctrl, &graph, 2);
+
+  if (ctrl.oflags&OFLAG_CCMP) 
+    MlevelNestedDissectionCC(&ctrl, &graph, iperm, ORDER_UNBALANCE_FRACTION, graph.nvtxs);
+  else
+    MlevelNestedDissection(&ctrl, &graph, iperm, ORDER_UNBALANCE_FRACTION, graph.nvtxs);
+
+  FreeWorkSpace(&ctrl, &graph);
+
+  if (ctrl.pfactor > 0) { /* Order any prunned vertices */
+    if (graph.nvtxs < *nvtxs) { 
+      idxcopy(graph.nvtxs, iperm, perm);  /* Use perm as an auxiliary array */
+      for (i=0; i<graph.nvtxs; i++)
+        iperm[piperm[i]] = perm[i];
+      for (i=graph.nvtxs; i<*nvtxs; i++)
+        iperm[piperm[i]] = i;
+    }
+
+    GKfree(&piperm, LTERM);
+  }
+  else if (ctrl.oflags&OFLAG_COMPRESS) { /* Uncompress the ordering */
+    if (graph.nvtxs < COMPRESSION_FRACTION*(*nvtxs)) { 
+      /* construct perm from iperm */
+      for (i=0; i<graph.nvtxs; i++)
+        perm[iperm[i]] = i; 
+      for (l=ii=0; ii<graph.nvtxs; ii++) {
+        i = perm[ii];
+        for (j=cptr[i]; j<cptr[i+1]; j++)
+          iperm[cind[j]] = l++;
+      }
+    }
+
+    GKfree(&cptr, &cind, LTERM);
+  }
+
+
+  for (i=0; i<*nvtxs; i++)
+    perm[iperm[i]] = i;
+
+  IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr));
+  IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl));
+
+  if (*numflag == 1)
+    Change2FNumberingOrder(*nvtxs, xadj, adjncy, perm, iperm);
+
+}
+
+
+/*************************************************************************
+* This function is the entry point for ONWMETIS. It requires weights on the
+* vertices. It is for the case that the matrix has been pre-compressed.
+**************************************************************************/
+void METIS_NodeWND(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, int *numflag, 
+                   int *options, idxtype *perm, idxtype *iperm) 
+{
+  int i, j, tvwgt;
+  GraphType graph;
+  CtrlType ctrl;
+
+  if (*numflag == 1)
+    Change2CNumbering(*nvtxs, xadj, adjncy);
+
+  SetUpGraph(&graph, OP_ONMETIS, *nvtxs, 1, xadj, adjncy, vwgt, NULL, 2);
+
+  if (options[0] == 0) {  /* Use the default parameters */
+    ctrl.CType = ONMETIS_CTYPE;
+    ctrl.IType = ONMETIS_ITYPE;
+    ctrl.RType = ONMETIS_RTYPE;
+    ctrl.dbglvl = ONMETIS_DBGLVL;
+  }
+  else {
+    ctrl.CType = options[OPTION_CTYPE];
+    ctrl.IType = options[OPTION_ITYPE];
+    ctrl.RType = options[OPTION_RTYPE];
+    ctrl.dbglvl = options[OPTION_DBGLVL];
+  }
+
+  ctrl.oflags  = OFLAG_COMPRESS;
+  ctrl.pfactor = 0;
+  ctrl.nseps = 2;
+  ctrl.optype = OP_ONMETIS;
+  ctrl.CoarsenTo = 100;
+  ctrl.maxvwgt = 1.5*(idxsum(*nvtxs, graph.vwgt)/ctrl.CoarsenTo);
+
+  InitRandom(-1);
+
+  AllocateWorkSpace(&ctrl, &graph, 2);
+
+  IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl));
+  IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr));
+
+  MlevelNestedDissection(&ctrl, &graph, iperm, ORDER_UNBALANCE_FRACTION, *nvtxs);
+
+  IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr));
+  IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl));
+
+  for (i=0; i<*nvtxs; i++)
+    perm[iperm[i]] = i;
+
+  FreeWorkSpace(&ctrl, &graph);
+
+  if (*numflag == 1)
+    Change2FNumberingOrder(*nvtxs, xadj, adjncy, perm, iperm);
+}
+
+
+
+
+/*************************************************************************
+* This function takes a graph and produces a bisection of it
+**************************************************************************/
+void MlevelNestedDissection(CtrlType *ctrl, GraphType *graph, idxtype *order, float ubfactor, int lastvtx)
+{
+  int i, j, nvtxs, nbnd, tvwgt, tpwgts2[2];
+  idxtype *label, *bndind;
+  GraphType lgraph, rgraph;
+
+  nvtxs = graph->nvtxs;
+
+  /* Determine the weights of the partitions */
+  tvwgt = idxsum(nvtxs, graph->vwgt);
+  tpwgts2[0] = tvwgt/2;
+  tpwgts2[1] = tvwgt-tpwgts2[0];
+
+  switch (ctrl->optype) {
+    case OP_OEMETIS:
+      MlevelEdgeBisection(ctrl, graph, tpwgts2, ubfactor);
+
+      IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->SepTmr));
+      ConstructMinCoverSeparator(ctrl, graph, ubfactor);
+      IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->SepTmr));
+
+      break;
+    case OP_ONMETIS:
+      MlevelNodeBisectionMultiple(ctrl, graph, tpwgts2, ubfactor);
+
+      IFSET(ctrl->dbglvl, DBG_SEPINFO, printf("Nvtxs: %6d, [%6d %6d %6d]\n", graph->nvtxs, graph->pwgts[0], graph->pwgts[1], graph->pwgts[2]));
+
+      break;
+  }
+
+  /* Order the nodes in the separator */
+  nbnd = graph->nbnd;
+  bndind = graph->bndind;
+  label = graph->label;
+  for (i=0; i<nbnd; i++) 
+    order[label[bndind[i]]] = --lastvtx;
+
+  SplitGraphOrder(ctrl, graph, &lgraph, &rgraph);
+
+  /* Free the memory of the top level graph */
+  GKfree(&graph->gdata, &graph->rdata, &graph->label, LTERM);
+
+  if (rgraph.nvtxs > MMDSWITCH) 
+    MlevelNestedDissection(ctrl, &rgraph, order, ubfactor, lastvtx);
+  else {
+    MMDOrder(ctrl, &rgraph, order, lastvtx); 
+    GKfree(&rgraph.gdata, &rgraph.rdata, &rgraph.label, LTERM);
+  }
+  if (lgraph.nvtxs > MMDSWITCH) 
+    MlevelNestedDissection(ctrl, &lgraph, order, ubfactor, lastvtx-rgraph.nvtxs);
+  else {
+    MMDOrder(ctrl, &lgraph, order, lastvtx-rgraph.nvtxs); 
+    GKfree(&lgraph.gdata, &lgraph.rdata, &lgraph.label, LTERM);
+  }
+}
+
+
+/*************************************************************************
+* This function takes a graph and produces a bisection of it
+**************************************************************************/
+void MlevelNestedDissectionCC(CtrlType *ctrl, GraphType *graph, idxtype *order, float ubfactor, int lastvtx)
+{
+  int i, j, nvtxs, nbnd, tvwgt, tpwgts2[2], nsgraphs, ncmps, rnvtxs;
+  idxtype *label, *bndind;
+  idxtype *cptr, *cind;
+  GraphType *sgraphs;
+
+  nvtxs = graph->nvtxs;
+
+  /* Determine the weights of the partitions */
+  tvwgt = idxsum(nvtxs, graph->vwgt);
+  tpwgts2[0] = tvwgt/2;
+  tpwgts2[1] = tvwgt-tpwgts2[0];
+
+  MlevelNodeBisectionMultiple(ctrl, graph, tpwgts2, ubfactor);
+  IFSET(ctrl->dbglvl, DBG_SEPINFO, printf("Nvtxs: %6d, [%6d %6d %6d]\n", graph->nvtxs, graph->pwgts[0], graph->pwgts[1], graph->pwgts[2]));
+
+  /* Order the nodes in the separator */
+  nbnd = graph->nbnd;
+  bndind = graph->bndind;
+  label = graph->label;
+  for (i=0; i<nbnd; i++) 
+    order[label[bndind[i]]] = --lastvtx;
+
+  cptr = idxmalloc(nvtxs, "MlevelNestedDissectionCC: cptr");
+  cind = idxmalloc(nvtxs, "MlevelNestedDissectionCC: cind");
+  ncmps = FindComponents(ctrl, graph, cptr, cind);
+
+/*
+  if (ncmps > 2)
+    printf("[%5d] has %3d components\n", nvtxs, ncmps);
+*/
+
+  sgraphs = (GraphType *)GKmalloc(ncmps*sizeof(GraphType), "MlevelNestedDissectionCC: sgraphs");
+
+  nsgraphs = SplitGraphOrderCC(ctrl, graph, sgraphs, ncmps, cptr, cind);
+
+  GKfree(&cptr, &cind, LTERM);
+
+  /* Free the memory of the top level graph */
+  GKfree(&graph->gdata, &graph->rdata, &graph->label, LTERM);
+
+  /* Go and process the subgraphs */
+  for (rnvtxs=i=0; i<nsgraphs; i++) {
+    if (sgraphs[i].adjwgt == NULL) {
+      MMDOrder(ctrl, sgraphs+i, order, lastvtx-rnvtxs);
+      GKfree(&sgraphs[i].gdata, &sgraphs[i].label, LTERM);
+    }
+    else {
+      MlevelNestedDissectionCC(ctrl, sgraphs+i, order, ubfactor, lastvtx-rnvtxs);
+    }
+    rnvtxs += sgraphs[i].nvtxs;
+  }
+
+  free(sgraphs);
+}
+
+
+
+/*************************************************************************
+* This function performs multilevel bisection. It performs multiple 
+* bisections and selects the best.
+**************************************************************************/
+void MlevelNodeBisectionMultiple(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor)
+{
+  int i, nvtxs, cnvtxs, mincut, tmp;
+  GraphType *cgraph; 
+  idxtype *bestwhere;
+
+  if (ctrl->nseps == 1 || graph->nvtxs < (ctrl->oflags&OFLAG_COMPRESS ? 1000 : 2000)) {
+    MlevelNodeBisection(ctrl, graph, tpwgts, ubfactor);
+    return;
+  }
+
+  nvtxs = graph->nvtxs;
+
+  if (ctrl->oflags&OFLAG_COMPRESS) { /* Multiple separators at the original graph */
+    bestwhere = idxmalloc(nvtxs, "MlevelNodeBisection2: bestwhere");
+    mincut = nvtxs;
+
+    for (i=ctrl->nseps; i>0; i--) {
+      MlevelNodeBisection(ctrl, graph, tpwgts, ubfactor);
+
+      /* printf("%5d ", cgraph->mincut); */
+
+      if (graph->mincut < mincut) {
+        mincut = graph->mincut;
+        idxcopy(nvtxs, graph->where, bestwhere);
+      }
+
+      GKfree(&graph->rdata, LTERM);
+    
+      if (mincut == 0)
+        break;
+    }
+    /* printf("[%5d]\n", mincut); */
+
+    Allocate2WayNodePartitionMemory(ctrl, graph);
+    idxcopy(nvtxs, bestwhere, graph->where);
+    free(bestwhere);
+
+    Compute2WayNodePartitionParams(ctrl, graph);
+  }
+  else {  /* Coarsen it a bit */
+    ctrl->CoarsenTo = nvtxs-1;
+
+    cgraph = Coarsen2Way(ctrl, graph);
+
+    cnvtxs = cgraph->nvtxs;
+
+    bestwhere = idxmalloc(cnvtxs, "MlevelNodeBisection2: bestwhere");
+    mincut = nvtxs;
+
+    for (i=ctrl->nseps; i>0; i--) {
+      ctrl->CType += 20; /* This is a hack. Look at coarsen.c */
+      MlevelNodeBisection(ctrl, cgraph, tpwgts, ubfactor);
+
+      /* printf("%5d ", cgraph->mincut); */
+
+      if (cgraph->mincut < mincut) {
+        mincut = cgraph->mincut;
+        idxcopy(cnvtxs, cgraph->where, bestwhere);
+      }
+
+      GKfree(&cgraph->rdata, LTERM);
+    
+      if (mincut == 0)
+        break;
+    }
+    /* printf("[%5d]\n", mincut); */
+
+    Allocate2WayNodePartitionMemory(ctrl, cgraph);
+    idxcopy(cnvtxs, bestwhere, cgraph->where);
+    free(bestwhere);
+
+    Compute2WayNodePartitionParams(ctrl, cgraph);
+
+    Refine2WayNode(ctrl, graph, cgraph, ubfactor);
+  }
+
+}
+
+/*************************************************************************
+* This function performs multilevel bisection
+**************************************************************************/
+void MlevelNodeBisection(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor)
+{
+  GraphType *cgraph;
+
+  ctrl->CoarsenTo = graph->nvtxs/8;
+  if (ctrl->CoarsenTo > 100)
+    ctrl->CoarsenTo = 100;
+  else if (ctrl->CoarsenTo < 40)
+    ctrl->CoarsenTo = 40;
+  ctrl->maxvwgt = 1.5*((tpwgts[0]+tpwgts[1])/ctrl->CoarsenTo);
+
+  cgraph = Coarsen2Way(ctrl, graph);
+
+  switch (ctrl->IType) {
+    case IPART_GGPKL:
+      Init2WayPartition(ctrl, cgraph, tpwgts, ubfactor);
+
+      IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->SepTmr));
+
+      Compute2WayPartitionParams(ctrl, cgraph);
+      ConstructSeparator(ctrl, cgraph, ubfactor);
+
+      IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->SepTmr));
+      break;
+    case IPART_GGPKLNODE:
+      InitSeparator(ctrl, cgraph, ubfactor);
+      break;
+  }
+
+  Refine2WayNode(ctrl, graph, cgraph, ubfactor);
+
+}
+
+
+
+
+/*************************************************************************
+* This function takes a graph and a bisection and splits it into two graphs.
+* This function relies on the fact that adjwgt is all equal to 1.
+**************************************************************************/
+void SplitGraphOrder(CtrlType *ctrl, GraphType *graph, GraphType *lgraph, GraphType *rgraph)
+{
+  int i, ii, j, k, l, istart, iend, mypart, nvtxs, snvtxs[3], snedges[3];
+  idxtype *xadj, *vwgt, *adjncy, *adjwgt, *adjwgtsum, *label, *where, *bndptr, *bndind;
+  idxtype *sxadj[2], *svwgt[2], *sadjncy[2], *sadjwgt[2], *sadjwgtsum[2], *slabel[2];
+  idxtype *rename;
+  idxtype *auxadjncy, *auxadjwgt;
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->SplitTmr));
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  vwgt = graph->vwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+  adjwgtsum = graph->adjwgtsum;
+  label = graph->label;
+  where = graph->where;
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+  ASSERT(bndptr != NULL);
+
+  rename = idxwspacemalloc(ctrl, nvtxs);
+  
+  snvtxs[0] = snvtxs[1] = snvtxs[2] = snedges[0] = snedges[1] = snedges[2] = 0;
+  for (i=0; i<nvtxs; i++) {
+    k = where[i];
+    rename[i] = snvtxs[k]++;
+    snedges[k] += xadj[i+1]-xadj[i];
+  }
+
+  SetUpSplitGraph(graph, lgraph, snvtxs[0], snedges[0]);
+  sxadj[0] = lgraph->xadj;
+  svwgt[0] = lgraph->vwgt;
+  sadjwgtsum[0] = lgraph->adjwgtsum;
+  sadjncy[0] = lgraph->adjncy; 
+  sadjwgt[0] = lgraph->adjwgt; 
+  slabel[0] = lgraph->label;
+
+  SetUpSplitGraph(graph, rgraph, snvtxs[1], snedges[1]);
+  sxadj[1] = rgraph->xadj;
+  svwgt[1] = rgraph->vwgt;
+  sadjwgtsum[1] = rgraph->adjwgtsum;
+  sadjncy[1] = rgraph->adjncy; 
+  sadjwgt[1] = rgraph->adjwgt; 
+  slabel[1] = rgraph->label;
+
+  /* Go and use bndptr to also mark the boundary nodes in the two partitions */
+  for (ii=0; ii<graph->nbnd; ii++) {
+    i = bndind[ii];
+    for (j=xadj[i]; j<xadj[i+1]; j++)
+      bndptr[adjncy[j]] = 1;
+  }
+
+  snvtxs[0] = snvtxs[1] = snedges[0] = snedges[1] = 0;
+  sxadj[0][0] = sxadj[1][0] = 0;
+  for (i=0; i<nvtxs; i++) {
+    if ((mypart = where[i]) == 2)
+      continue;
+
+    istart = xadj[i];
+    iend = xadj[i+1];
+    if (bndptr[i] == -1) { /* This is an interior vertex */
+      auxadjncy = sadjncy[mypart] + snedges[mypart] - istart;
+      for(j=istart; j<iend; j++) 
+        auxadjncy[j] = adjncy[j];
+      snedges[mypart] += iend-istart;
+    }
+    else {
+      auxadjncy = sadjncy[mypart];
+      l = snedges[mypart];
+      for (j=istart; j<iend; j++) {
+        k = adjncy[j];
+        if (where[k] == mypart) 
+          auxadjncy[l++] = k;
+      }
+      snedges[mypart] = l;
+    }
+
+    svwgt[mypart][snvtxs[mypart]] = vwgt[i];
+    sadjwgtsum[mypart][snvtxs[mypart]] = snedges[mypart]-sxadj[mypart][snvtxs[mypart]];
+    slabel[mypart][snvtxs[mypart]] = label[i];
+    sxadj[mypart][++snvtxs[mypart]] = snedges[mypart];
+  }
+
+  for (mypart=0; mypart<2; mypart++) {
+    iend = snedges[mypart];
+    idxset(iend, 1, sadjwgt[mypart]);
+
+    auxadjncy = sadjncy[mypart];
+    for (i=0; i<iend; i++) 
+      auxadjncy[i] = rename[auxadjncy[i]];
+  }
+
+  lgraph->nvtxs = snvtxs[0];
+  lgraph->nedges = snedges[0];
+  rgraph->nvtxs = snvtxs[1];
+  rgraph->nedges = snedges[1];
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->SplitTmr));
+
+  idxwspacefree(ctrl, nvtxs);
+
+}
+
+/*************************************************************************
+* This function uses MMD to order the graph. The vertices are numbered
+* from lastvtx downwards
+**************************************************************************/
+void MMDOrder(CtrlType *ctrl, GraphType *graph, idxtype *order, int lastvtx)
+{
+  int i, j, k, nvtxs, nofsub, firstvtx;
+  idxtype *xadj, *adjncy, *label;
+  idxtype *perm, *iperm, *head, *qsize, *list, *marker;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+
+  /* Relabel the vertices so that it starts from 1 */
+  k = xadj[nvtxs];
+  for (i=0; i<k; i++)
+    adjncy[i]++;
+  for (i=0; i<nvtxs+1; i++)
+    xadj[i]++;
+
+  perm = idxmalloc(6*(nvtxs+5), "MMDOrder: perm");
+  iperm = perm + nvtxs + 5;
+  head = iperm + nvtxs + 5;
+  qsize = head + nvtxs + 5;
+  list = qsize + nvtxs + 5;
+  marker = list + nvtxs + 5;
+
+  genmmd(nvtxs, xadj, adjncy, iperm, perm, 1, head, qsize, list, marker, MAXIDX, &nofsub);
+
+  label = graph->label;
+  firstvtx = lastvtx-nvtxs;
+  for (i=0; i<nvtxs; i++)
+    order[label[i]] = firstvtx+iperm[i]-1;
+
+  free(perm);
+
+  /* Relabel the vertices so that it starts from 0 */
+  for (i=0; i<nvtxs+1; i++)
+    xadj[i]--;
+  k = xadj[nvtxs];
+  for (i=0; i<k; i++)
+    adjncy[i]--;
+}
+
+
+/*************************************************************************
+* This function takes a graph and a bisection and splits it into two graphs.
+* It relies on the fact that adjwgt is all set to 1.
+**************************************************************************/
+int SplitGraphOrderCC(CtrlType *ctrl, GraphType *graph, GraphType *sgraphs, int ncmps, idxtype *cptr, idxtype *cind)
+{
+  int i, ii, iii, j, k, l, istart, iend, mypart, nvtxs, snvtxs, snedges;
+  idxtype *xadj, *vwgt, *adjncy, *adjwgt, *adjwgtsum, *label, *where, *bndptr, *bndind;
+  idxtype *sxadj, *svwgt, *sadjncy, *sadjwgt, *sadjwgtsum, *slabel;
+  idxtype *rename;
+  idxtype *auxadjncy, *auxadjwgt;
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->SplitTmr));
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  vwgt = graph->vwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+  adjwgtsum = graph->adjwgtsum;
+  label = graph->label;
+  where = graph->where;
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+  ASSERT(bndptr != NULL);
+
+  /* Go and use bndptr to also mark the boundary nodes in the two partitions */
+  for (ii=0; ii<graph->nbnd; ii++) {
+    i = bndind[ii];
+    for (j=xadj[i]; j<xadj[i+1]; j++)
+      bndptr[adjncy[j]] = 1;
+  }
+
+  rename = idxwspacemalloc(ctrl, nvtxs);
+  
+  /* Go and split the graph a component at a time */
+  for (iii=0; iii<ncmps; iii++) {
+    RandomPermute(cptr[iii+1]-cptr[iii], cind+cptr[iii], 0);
+    snvtxs = snedges = 0;
+    for (j=cptr[iii]; j<cptr[iii+1]; j++) {
+      i = cind[j];
+      rename[i] = snvtxs++;
+      snedges += xadj[i+1]-xadj[i];
+    }
+
+    SetUpSplitGraph(graph, sgraphs+iii, snvtxs, snedges);
+    sxadj = sgraphs[iii].xadj;
+    svwgt = sgraphs[iii].vwgt;
+    sadjwgtsum = sgraphs[iii].adjwgtsum;
+    sadjncy = sgraphs[iii].adjncy;
+    sadjwgt = sgraphs[iii].adjwgt;
+    slabel = sgraphs[iii].label;
+
+    snvtxs = snedges = sxadj[0] = 0;
+    for (ii=cptr[iii]; ii<cptr[iii+1]; ii++) {
+      i = cind[ii];
+
+      istart = xadj[i];
+      iend = xadj[i+1];
+      if (bndptr[i] == -1) { /* This is an interior vertex */
+        auxadjncy = sadjncy + snedges - istart;
+        auxadjwgt = sadjwgt + snedges - istart;
+        for(j=istart; j<iend; j++) 
+          auxadjncy[j] = adjncy[j];
+        snedges += iend-istart;
+      }
+      else {
+        l = snedges;
+        for (j=istart; j<iend; j++) {
+          k = adjncy[j];
+          if (where[k] != 2) 
+            sadjncy[l++] = k;
+        }
+        snedges = l;
+      }
+
+      svwgt[snvtxs] = vwgt[i];
+      sadjwgtsum[snvtxs] = snedges-sxadj[snvtxs];
+      slabel[snvtxs] = label[i];
+      sxadj[++snvtxs] = snedges;
+    }
+
+    idxset(snedges, 1, sadjwgt);
+    for (i=0; i<snedges; i++) 
+      sadjncy[i] = rename[sadjncy[i]];
+
+    sgraphs[iii].nvtxs = snvtxs;
+    sgraphs[iii].nedges = snedges;
+    sgraphs[iii].ncon = 1;
+
+    if (snvtxs < MMDSWITCH)
+      sgraphs[iii].adjwgt = NULL;  /* A marker to call MMD on the driver */
+  }
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->SplitTmr));
+
+  idxwspacefree(ctrl, nvtxs);
+
+  return ncmps;
+
+}
+
+
+
+
+
diff --git a/Metis/parmetis.c b/Metis/parmetis.c
new file mode 100644
index 0000000000..b20396a551
--- /dev/null
+++ b/Metis/parmetis.c
@@ -0,0 +1,371 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * parmetis.c
+ *
+ * This file contains top level routines that are used by ParMETIS
+ *
+ * Started 10/14/97
+ * George
+ *
+ * $Id: parmetis.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function is the entry point for KMETIS with seed specification
+* in options[7] 
+**************************************************************************/
+void METIS_PartGraphKway2(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, 
+                         idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, 
+                         int *options, int *edgecut, idxtype *part)
+{
+  int i;
+  float *tpwgts;
+
+  tpwgts = fmalloc(*nparts, "KMETIS: tpwgts");
+  for (i=0; i<*nparts; i++) 
+    tpwgts[i] = 1.0/(1.0*(*nparts));
+
+  METIS_WPartGraphKway2(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, 
+                       tpwgts, options, edgecut, part);
+
+  free(tpwgts);
+}
+
+
+/*************************************************************************
+* This function is the entry point for KWMETIS with seed specification
+* in options[7] 
+**************************************************************************/
+void METIS_WPartGraphKway2(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, 
+                          idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, 
+                          float *tpwgts, int *options, int *edgecut, idxtype *part)
+{
+  int i, j;
+  GraphType graph;
+  CtrlType ctrl;
+
+  if (*numflag == 1)
+    Change2CNumbering(*nvtxs, xadj, adjncy);
+
+  SetUpGraph(&graph, OP_KMETIS, *nvtxs, 1, xadj, adjncy, vwgt, adjwgt, *wgtflag);
+
+  if (options[0] == 0) {  /* Use the default parameters */
+    ctrl.CType = KMETIS_CTYPE;
+    ctrl.IType = KMETIS_ITYPE;
+    ctrl.RType = KMETIS_RTYPE;
+    ctrl.dbglvl = KMETIS_DBGLVL;
+  }
+  else {
+    ctrl.CType = options[OPTION_CTYPE];
+    ctrl.IType = options[OPTION_ITYPE];
+    ctrl.RType = options[OPTION_RTYPE];
+    ctrl.dbglvl = options[OPTION_DBGLVL];
+  }
+  ctrl.optype = OP_KMETIS;
+  ctrl.CoarsenTo = 20*(*nparts);
+  ctrl.maxvwgt = 1.5*((graph.vwgt ? idxsum(*nvtxs, graph.vwgt) : (*nvtxs))/ctrl.CoarsenTo);
+
+  InitRandom(options[7]);
+
+  AllocateWorkSpace(&ctrl, &graph, *nparts);
+
+  IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl));
+  IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr));
+
+  *edgecut = MlevelKWayPartitioning(&ctrl, &graph, *nparts, part, tpwgts, 1.03);
+
+  IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr));
+  IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl));
+
+  FreeWorkSpace(&ctrl, &graph);
+
+  if (*numflag == 1)
+    Change2FNumbering(*nvtxs, xadj, adjncy, part);
+}
+
+
+/*************************************************************************
+* This function is the entry point for the node ND code for ParMETIS
+**************************************************************************/
+void METIS_NodeNDP(int nvtxs, idxtype *xadj, idxtype *adjncy, int npes, 
+                   int *options, idxtype *perm, idxtype *iperm, idxtype *sizes) 
+{
+  int i, ii, j, l, wflag, nflag;
+  GraphType graph;
+  CtrlType ctrl;
+  idxtype *cptr, *cind;
+
+  if (options[0] == 0) {  /* Use the default parameters */
+    ctrl.CType   = ONMETIS_CTYPE;
+    ctrl.IType   = ONMETIS_ITYPE;
+    ctrl.RType   = ONMETIS_RTYPE;
+    ctrl.dbglvl  = ONMETIS_DBGLVL;
+    ctrl.oflags  = ONMETIS_OFLAGS;
+    ctrl.pfactor = ONMETIS_PFACTOR;
+    ctrl.nseps   = ONMETIS_NSEPS;
+  }
+  else {
+    ctrl.CType   = options[OPTION_CTYPE];
+    ctrl.IType   = options[OPTION_ITYPE];
+    ctrl.RType   = options[OPTION_RTYPE];
+    ctrl.dbglvl  = options[OPTION_DBGLVL];
+    ctrl.oflags  = options[OPTION_OFLAGS];
+    ctrl.pfactor = options[OPTION_PFACTOR];
+    ctrl.nseps   = options[OPTION_NSEPS];
+  }
+  if (ctrl.nseps < 1)
+    ctrl.nseps = 1;
+
+  ctrl.optype = OP_ONMETIS;
+  ctrl.CoarsenTo = 100;
+
+  IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl));
+  IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr));
+
+  InitRandom(-1);
+
+  if (ctrl.oflags&OFLAG_COMPRESS) {
+    /*============================================================
+    * Compress the graph 
+    ==============================================================*/
+    cptr = idxmalloc(nvtxs+1, "ONMETIS: cptr");
+    cind = idxmalloc(nvtxs, "ONMETIS: cind");
+
+    CompressGraph(&ctrl, &graph, nvtxs, xadj, adjncy, cptr, cind);
+
+    if (graph.nvtxs >= COMPRESSION_FRACTION*(nvtxs)) {
+      ctrl.oflags--; /* We actually performed no compression */
+      GKfree(&cptr, &cind, LTERM);
+    }
+    else if (2*graph.nvtxs < nvtxs && ctrl.nseps == 1)
+      ctrl.nseps = 2;
+  }
+  else {
+    SetUpGraph(&graph, OP_ONMETIS, nvtxs, 1, xadj, adjncy, NULL, NULL, 0);
+  }
+
+
+  /*=============================================================
+  * Do the nested dissection ordering 
+  --=============================================================*/
+  ctrl.maxvwgt = 1.5*(idxsum(graph.nvtxs, graph.vwgt)/ctrl.CoarsenTo);
+  AllocateWorkSpace(&ctrl, &graph, 2);
+
+  idxset(2*npes-1, 0, sizes);
+  MlevelNestedDissectionP(&ctrl, &graph, iperm, graph.nvtxs, npes, 0, sizes);
+
+  FreeWorkSpace(&ctrl, &graph);
+
+  if (ctrl.oflags&OFLAG_COMPRESS) { /* Uncompress the ordering */
+    if (graph.nvtxs < COMPRESSION_FRACTION*(nvtxs)) { 
+      /* construct perm from iperm */
+      for (i=0; i<graph.nvtxs; i++)
+        perm[iperm[i]] = i; 
+      for (l=ii=0; ii<graph.nvtxs; ii++) {
+        i = perm[ii];
+        for (j=cptr[i]; j<cptr[i+1]; j++)
+          iperm[cind[j]] = l++;
+      }
+    }
+
+    GKfree(&cptr, &cind, LTERM);
+  }
+
+
+  for (i=0; i<nvtxs; i++)
+    perm[iperm[i]] = i;
+
+  IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr));
+  IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl));
+
+}
+
+
+
+/*************************************************************************
+* This function takes a graph and produces a bisection of it
+**************************************************************************/
+void MlevelNestedDissectionP(CtrlType *ctrl, GraphType *graph, idxtype *order, int lastvtx, 
+                             int npes, int cpos, idxtype *sizes)
+{
+  int i, j, nvtxs, nbnd, tvwgt, tpwgts2[2];
+  idxtype *label, *bndind;
+  GraphType lgraph, rgraph;
+  float ubfactor;
+
+  nvtxs = graph->nvtxs;
+
+  if (nvtxs == 0) {
+    GKfree(&graph->gdata, &graph->rdata, &graph->label, LTERM);
+    return;
+  }
+
+  /* Determine the weights of the partitions */
+  tvwgt = idxsum(nvtxs, graph->vwgt);
+  tpwgts2[0] = tvwgt/2;
+  tpwgts2[1] = tvwgt-tpwgts2[0];
+
+  if (cpos >= npes-1) 
+    ubfactor = ORDER_UNBALANCE_FRACTION;
+  else 
+    ubfactor = 1.05;
+
+
+  MlevelNodeBisectionMultiple(ctrl, graph, tpwgts2, ubfactor);
+
+  IFSET(ctrl->dbglvl, DBG_SEPINFO, printf("Nvtxs: %6d, [%6d %6d %6d]\n", graph->nvtxs, graph->pwgts[0], graph->pwgts[1], graph->pwgts[2]));
+
+  if (cpos < npes-1) {
+    sizes[2*npes-2-cpos] = graph->pwgts[2];
+    sizes[2*npes-2-(2*cpos+1)] = graph->pwgts[1];
+    sizes[2*npes-2-(2*cpos+2)] = graph->pwgts[0];
+  }
+
+  /* Order the nodes in the separator */
+  nbnd = graph->nbnd;
+  bndind = graph->bndind;
+  label = graph->label;
+  for (i=0; i<nbnd; i++) 
+    order[label[bndind[i]]] = --lastvtx;
+
+  SplitGraphOrder(ctrl, graph, &lgraph, &rgraph);
+
+  /* Free the memory of the top level graph */
+  GKfree(&graph->gdata, &graph->rdata, &graph->label, LTERM);
+
+  if (rgraph.nvtxs > MMDSWITCH || 2*cpos+1 < npes-1) 
+    MlevelNestedDissectionP(ctrl, &rgraph, order, lastvtx, npes, 2*cpos+1, sizes);
+  else {
+    MMDOrder(ctrl, &rgraph, order, lastvtx); 
+    GKfree(&rgraph.gdata, &rgraph.rdata, &rgraph.label, LTERM);
+  }
+  if (lgraph.nvtxs > MMDSWITCH || 2*cpos+2 < npes-1) 
+    MlevelNestedDissectionP(ctrl, &lgraph, order, lastvtx-rgraph.nvtxs, npes, 2*cpos+2, sizes);
+  else {
+    MMDOrder(ctrl, &lgraph, order, lastvtx-rgraph.nvtxs); 
+    GKfree(&lgraph.gdata, &lgraph.rdata, &lgraph.label, LTERM);
+  }
+}
+
+
+
+
+/*************************************************************************
+* This function is the entry point for ONWMETIS. It requires weights on the
+* vertices. It is for the case that the matrix has been pre-compressed.
+**************************************************************************/
+void METIS_NodeComputeSeparator(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, 
+           idxtype *adjwgt, int *options, int *sepsize, idxtype *part) 
+{
+  int i, j, tvwgt, tpwgts[2];
+  GraphType graph;
+  CtrlType ctrl;
+
+  SetUpGraph(&graph, OP_ONMETIS, *nvtxs, 1, xadj, adjncy, vwgt, adjwgt, 3);
+  tvwgt = idxsum(*nvtxs, graph.vwgt);
+
+  if (options[0] == 0) {  /* Use the default parameters */
+    ctrl.CType = ONMETIS_CTYPE;
+    ctrl.IType = ONMETIS_ITYPE;
+    ctrl.RType = ONMETIS_RTYPE;
+    ctrl.dbglvl = ONMETIS_DBGLVL;
+  }
+  else {
+    ctrl.CType = options[OPTION_CTYPE];
+    ctrl.IType = options[OPTION_ITYPE];
+    ctrl.RType = options[OPTION_RTYPE];
+    ctrl.dbglvl = options[OPTION_DBGLVL];
+  }
+
+  ctrl.oflags  = 0;
+  ctrl.pfactor = 0;
+  ctrl.nseps = 1;
+  ctrl.optype = OP_ONMETIS;
+  ctrl.CoarsenTo = amin(100, *nvtxs-1);
+  ctrl.maxvwgt = 1.5*tvwgt/ctrl.CoarsenTo;
+
+  InitRandom(options[7]);
+
+  AllocateWorkSpace(&ctrl, &graph, 2);
+
+  /*============================================================
+   * Perform the bisection
+   *============================================================*/ 
+  tpwgts[0] = tvwgt/2;
+  tpwgts[1] = tvwgt-tpwgts[0];
+
+  MlevelNodeBisectionMultiple(&ctrl, &graph, tpwgts, 1.05);
+
+  *sepsize = graph.pwgts[2];
+  idxcopy(*nvtxs, graph.where, part);
+
+  GKfree(&graph.gdata, &graph.rdata, &graph.label, LTERM);
+
+
+  FreeWorkSpace(&ctrl, &graph);
+
+}
+
+
+
+/*************************************************************************
+* This function is the entry point for ONWMETIS. It requires weights on the
+* vertices. It is for the case that the matrix has been pre-compressed.
+**************************************************************************/
+void METIS_EdgeComputeSeparator(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, 
+           idxtype *adjwgt, int *options, int *sepsize, idxtype *part) 
+{
+  int i, j, tvwgt, tpwgts[2];
+  GraphType graph;
+  CtrlType ctrl;
+
+  SetUpGraph(&graph, OP_ONMETIS, *nvtxs, 1, xadj, adjncy, vwgt, adjwgt, 3);
+  tvwgt = idxsum(*nvtxs, graph.vwgt);
+
+  if (options[0] == 0) {  /* Use the default parameters */
+    ctrl.CType = ONMETIS_CTYPE;
+    ctrl.IType = ONMETIS_ITYPE;
+    ctrl.RType = ONMETIS_RTYPE;
+    ctrl.dbglvl = ONMETIS_DBGLVL;
+  }
+  else {
+    ctrl.CType = options[OPTION_CTYPE];
+    ctrl.IType = options[OPTION_ITYPE];
+    ctrl.RType = options[OPTION_RTYPE];
+    ctrl.dbglvl = options[OPTION_DBGLVL];
+  }
+
+  ctrl.oflags  = 0;
+  ctrl.pfactor = 0;
+  ctrl.nseps = 1;
+  ctrl.optype = OP_OEMETIS;
+  ctrl.CoarsenTo = amin(100, *nvtxs-1);
+  ctrl.maxvwgt = 1.5*tvwgt/ctrl.CoarsenTo;
+
+  InitRandom(options[7]);
+
+  AllocateWorkSpace(&ctrl, &graph, 2);
+
+  /*============================================================
+   * Perform the bisection
+   *============================================================*/ 
+  tpwgts[0] = tvwgt/2;
+  tpwgts[1] = tvwgt-tpwgts[0];
+
+  MlevelEdgeBisection(&ctrl, &graph, tpwgts, 1.05);
+  ConstructMinCoverSeparator(&ctrl, &graph, 1.05);
+
+  *sepsize = graph.pwgts[2];
+  idxcopy(*nvtxs, graph.where, part);
+
+  GKfree(&graph.gdata, &graph.rdata, &graph.label, LTERM);
+
+
+  FreeWorkSpace(&ctrl, &graph);
+
+}
diff --git a/Metis/pmetis.c b/Metis/pmetis.c
new file mode 100644
index 0000000000..9e17cdfe73
--- /dev/null
+++ b/Metis/pmetis.c
@@ -0,0 +1,341 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * pmetis.c
+ *
+ * This file contains the top level routines for the multilevel recursive
+ * bisection algorithm PMETIS.
+ *
+ * Started 7/24/97
+ * George
+ *
+ * $Id: pmetis.c,v 1.1 2005-09-07 14:36:46 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function is the entry point for PMETIS
+**************************************************************************/
+void METIS_PartGraphRecursive(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, 
+                              idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, 
+                              int *options, int *edgecut, idxtype *part)
+{
+  int i;
+  float *tpwgts;
+
+  tpwgts = fmalloc(*nparts, "KMETIS: tpwgts");
+  for (i=0; i<*nparts; i++) 
+    tpwgts[i] = 1.0/(1.0*(*nparts));
+
+  METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, 
+                            tpwgts, options, edgecut, part);
+
+  free(tpwgts);
+}
+
+
+
+/*************************************************************************
+* This function is the entry point for PWMETIS that accepts exact weights
+* for the target partitions
+**************************************************************************/
+void METIS_WPartGraphRecursive(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, 
+                               idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, 
+                               float *tpwgts, int *options, int *edgecut, idxtype *part)
+{
+  int i, j;
+  GraphType graph;
+  CtrlType ctrl;
+  float *mytpwgts;
+
+  if (*numflag == 1)
+    Change2CNumbering(*nvtxs, xadj, adjncy);
+
+  SetUpGraph(&graph, OP_PMETIS, *nvtxs, 1, xadj, adjncy, vwgt, adjwgt, *wgtflag);
+
+  if (options[0] == 0) {  /* Use the default parameters */
+    ctrl.CType = PMETIS_CTYPE;
+    ctrl.IType = PMETIS_ITYPE;
+    ctrl.RType = PMETIS_RTYPE;
+    ctrl.dbglvl = PMETIS_DBGLVL;
+  }
+  else {
+    ctrl.CType = options[OPTION_CTYPE];
+    ctrl.IType = options[OPTION_ITYPE];
+    ctrl.RType = options[OPTION_RTYPE];
+    ctrl.dbglvl = options[OPTION_DBGLVL];
+  }
+  ctrl.optype = OP_PMETIS;
+  ctrl.CoarsenTo = 20;
+  ctrl.maxvwgt = 1.5*(idxsum(*nvtxs, graph.vwgt)/ctrl.CoarsenTo);
+
+  mytpwgts = fmalloc(*nparts, "PWMETIS: mytpwgts");
+  for (i=0; i<*nparts; i++) 
+    mytpwgts[i] = tpwgts[i];
+
+  InitRandom(-1);
+
+  AllocateWorkSpace(&ctrl, &graph, *nparts);
+
+  IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl));
+  IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr));
+
+  *edgecut = MlevelRecursiveBisection(&ctrl, &graph, *nparts, part, mytpwgts, 1.000, 0);
+
+  IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr));
+  IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl));
+
+  FreeWorkSpace(&ctrl, &graph);
+  free(mytpwgts);
+
+  if (*numflag == 1)
+    Change2FNumbering(*nvtxs, xadj, adjncy, part);
+}
+
+
+
+/*************************************************************************
+* This function takes a graph and produces a bisection of it
+**************************************************************************/
+int MlevelRecursiveBisection(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, float *tpwgts, float ubfactor, int fpart)
+{
+  int i, j, nvtxs, cut, tvwgt, tpwgts2[2];
+  idxtype *label, *where;
+  GraphType lgraph, rgraph;
+  float wsum;
+
+  nvtxs = graph->nvtxs;
+  if (nvtxs == 0) {
+    printf("\t***Cannot bisect a graph with 0 vertices!\n\t***You are trying to partition a graph into too many parts!\n");
+    return 0;
+  }
+
+  /* Determine the weights of the partitions */
+  tvwgt = idxsum(nvtxs, graph->vwgt);
+  tpwgts2[0] = tvwgt*ssum(nparts/2, tpwgts);
+  tpwgts2[1] = tvwgt-tpwgts2[0];
+
+  MlevelEdgeBisection(ctrl, graph, tpwgts2, ubfactor);
+  cut = graph->mincut;
+
+  /* printf("%5d %5d %5d [%5d %f]\n", tpwgts2[0], tpwgts2[1], cut, tvwgt, ssum(nparts/2, tpwgts));*/
+
+  label = graph->label;
+  where = graph->where;
+  for (i=0; i<nvtxs; i++)
+    part[label[i]] = where[i] + fpart;
+
+  if (nparts > 2) {
+    SplitGraphPart(ctrl, graph, &lgraph, &rgraph);
+    /* printf("%d %d\n", lgraph.nvtxs, rgraph.nvtxs); */
+  }
+
+
+  /* Free the memory of the top level graph */
+  GKfree(&graph->gdata, &graph->rdata, &graph->label, LTERM);
+
+  /* Scale the fractions in the tpwgts according to the true weight */
+  wsum = ssum(nparts/2, tpwgts);
+  sscale(nparts/2, 1.0/wsum, tpwgts);
+  sscale(nparts-nparts/2, 1.0/(1.0-wsum), tpwgts+nparts/2);
+  /*
+  for (i=0; i<nparts; i++)
+    printf("%5.3f ", tpwgts[i]);
+  printf("[%5.3f]\n", wsum);
+  */
+
+  /* Do the recursive call */
+  if (nparts > 3) {
+    cut += MlevelRecursiveBisection(ctrl, &lgraph, nparts/2, part, tpwgts, ubfactor, fpart);
+    cut += MlevelRecursiveBisection(ctrl, &rgraph, nparts-nparts/2, part, tpwgts+nparts/2, ubfactor, fpart+nparts/2);
+  }
+  else if (nparts == 3) {
+    cut += MlevelRecursiveBisection(ctrl, &rgraph, nparts-nparts/2, part, tpwgts+nparts/2, ubfactor, fpart+nparts/2);
+    GKfree(&lgraph.gdata, &lgraph.label, LTERM);
+  }
+
+  return cut;
+
+}
+
+
+/*************************************************************************
+* This function performs multilevel bisection
+**************************************************************************/
+void MlevelEdgeBisection(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor)
+{
+  GraphType *cgraph;
+
+  cgraph = Coarsen2Way(ctrl, graph);
+
+  Init2WayPartition(ctrl, cgraph, tpwgts, ubfactor);
+
+  Refine2Way(ctrl, graph, cgraph, tpwgts, ubfactor);
+
+/*
+  IsConnectedSubdomain(ctrl, graph, 0);
+  IsConnectedSubdomain(ctrl, graph, 1);
+*/
+}
+
+
+
+
+/*************************************************************************
+* This function takes a graph and a bisection and splits it into two graphs.
+**************************************************************************/
+void SplitGraphPart(CtrlType *ctrl, GraphType *graph, GraphType *lgraph, GraphType *rgraph)
+{
+  int i, j, k, kk, l, istart, iend, mypart, nvtxs, ncon, snvtxs[2], snedges[2], sum;
+  idxtype *xadj, *vwgt, *adjncy, *adjwgt, *adjwgtsum, *label, *where, *bndptr;
+  idxtype *sxadj[2], *svwgt[2], *sadjncy[2], *sadjwgt[2], *sadjwgtsum[2], *slabel[2];
+  idxtype *rename;
+  idxtype *auxadjncy, *auxadjwgt;
+  float *nvwgt, *snvwgt[2], *npwgts;
+
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->SplitTmr));
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  xadj = graph->xadj;
+  vwgt = graph->vwgt;
+  nvwgt = graph->nvwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+  adjwgtsum = graph->adjwgtsum;
+  label = graph->label;
+  where = graph->where;
+  bndptr = graph->bndptr;
+  npwgts = graph->npwgts;
+
+  ASSERT(bndptr != NULL);
+
+  rename = idxwspacemalloc(ctrl, nvtxs);
+  
+  snvtxs[0] = snvtxs[1] = snedges[0] = snedges[1] = 0;
+  for (i=0; i<nvtxs; i++) {
+    k = where[i];
+    rename[i] = snvtxs[k]++;
+    snedges[k] += xadj[i+1]-xadj[i];
+  }
+
+  SetUpSplitGraph(graph, lgraph, snvtxs[0], snedges[0]);
+  sxadj[0] = lgraph->xadj;
+  svwgt[0] = lgraph->vwgt;
+  snvwgt[0] = lgraph->nvwgt;
+  sadjwgtsum[0] = lgraph->adjwgtsum;
+  sadjncy[0] = lgraph->adjncy; 	
+  sadjwgt[0] = lgraph->adjwgt; 
+  slabel[0] = lgraph->label;
+
+  SetUpSplitGraph(graph, rgraph, snvtxs[1], snedges[1]);
+  sxadj[1] = rgraph->xadj;
+  svwgt[1] = rgraph->vwgt;
+  snvwgt[1] = rgraph->nvwgt;
+  sadjwgtsum[1] = rgraph->adjwgtsum;
+  sadjncy[1] = rgraph->adjncy; 	
+  sadjwgt[1] = rgraph->adjwgt; 
+  slabel[1] = rgraph->label;
+
+  snvtxs[0] = snvtxs[1] = snedges[0] = snedges[1] = 0;
+  sxadj[0][0] = sxadj[1][0] = 0;
+  for (i=0; i<nvtxs; i++) {
+    mypart = where[i];
+    sum = adjwgtsum[i];
+
+    istart = xadj[i];
+    iend = xadj[i+1];
+    if (bndptr[i] == -1) { /* This is an interior vertex */
+      auxadjncy = sadjncy[mypart] + snedges[mypart] - istart;
+      auxadjwgt = sadjwgt[mypart] + snedges[mypart] - istart;
+      for(j=istart; j<iend; j++) {
+        auxadjncy[j] = adjncy[j];
+        auxadjwgt[j] = adjwgt[j]; 
+      }
+      snedges[mypart] += iend-istart;
+    }
+    else {
+      auxadjncy = sadjncy[mypart];
+      auxadjwgt = sadjwgt[mypart];
+      l = snedges[mypart];
+      for (j=istart; j<iend; j++) {
+        k = adjncy[j];
+        if (where[k] == mypart) {
+          auxadjncy[l] = k;
+          auxadjwgt[l++] = adjwgt[j]; 
+        }
+        else {
+          sum -= adjwgt[j];
+        }
+      }
+      snedges[mypart] = l;
+    }
+
+    if (ncon == 1)
+      svwgt[mypart][snvtxs[mypart]] = vwgt[i];
+    else {
+      for (kk=0; kk<ncon; kk++)
+        snvwgt[mypart][snvtxs[mypart]*ncon+kk] = nvwgt[i*ncon+kk]/npwgts[mypart*ncon+kk];
+    }
+
+    sadjwgtsum[mypart][snvtxs[mypart]] = sum;
+    slabel[mypart][snvtxs[mypart]] = label[i];
+    sxadj[mypart][++snvtxs[mypart]] = snedges[mypart];
+  }
+
+  for (mypart=0; mypart<2; mypart++) {
+    iend = sxadj[mypart][snvtxs[mypart]];
+    auxadjncy = sadjncy[mypart];
+    for (i=0; i<iend; i++) 
+      auxadjncy[i] = rename[auxadjncy[i]];
+  }
+
+  lgraph->nedges = snedges[0];
+  rgraph->nedges = snedges[1];
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->SplitTmr));
+
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+/*************************************************************************
+* Setup the various arrays for the splitted graph
+**************************************************************************/
+void SetUpSplitGraph(GraphType *graph, GraphType *sgraph, int snvtxs, int snedges)
+{
+  InitGraph(sgraph);
+  sgraph->nvtxs = snvtxs;
+  sgraph->nedges = snedges;
+  sgraph->ncon = graph->ncon;
+
+  /* Allocate memory for the splitted graph */
+  if (graph->ncon == 1) {
+    sgraph->gdata = idxmalloc(4*snvtxs+1 + 2*snedges, "SetUpSplitGraph: gdata");
+
+    sgraph->xadj        = sgraph->gdata;
+    sgraph->vwgt        = sgraph->gdata + snvtxs+1;
+    sgraph->adjwgtsum   = sgraph->gdata + 2*snvtxs+1;
+    sgraph->cmap        = sgraph->gdata + 3*snvtxs+1;
+    sgraph->adjncy      = sgraph->gdata + 4*snvtxs+1;
+    sgraph->adjwgt      = sgraph->gdata + 4*snvtxs+1 + snedges;
+  }
+  else {
+    sgraph->gdata = idxmalloc(3*snvtxs+1 + 2*snedges, "SetUpSplitGraph: gdata");
+
+    sgraph->xadj        = sgraph->gdata;
+    sgraph->adjwgtsum   = sgraph->gdata + snvtxs+1;
+    sgraph->cmap        = sgraph->gdata + 2*snvtxs+1;
+    sgraph->adjncy      = sgraph->gdata + 3*snvtxs+1;
+    sgraph->adjwgt      = sgraph->gdata + 3*snvtxs+1 + snedges;
+
+    sgraph->nvwgt       = fmalloc(graph->ncon*snvtxs, "SetUpSplitGraph: nvwgt");
+  }
+
+  sgraph->label	= idxmalloc(snvtxs, "SetUpSplitGraph: sgraph->label");
+}
+
diff --git a/Metis/pqueue.c b/Metis/pqueue.c
new file mode 100644
index 0000000000..c5b8c8b3b5
--- /dev/null
+++ b/Metis/pqueue.c
@@ -0,0 +1,579 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * pqueue.c
+ *
+ * This file contains functions for manipulating the bucket list
+ * representation of the gains associated with each vertex in a graph.
+ * These functions are used by the refinement algorithms
+ *
+ * Started 9/2/94
+ * George
+ *
+ * $Id: pqueue.c,v 1.1 2005-09-07 14:36:46 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function initializes the data structures of the priority queue
+**************************************************************************/
+void PQueueInit(CtrlType *ctrl, PQueueType *queue, int maxnodes, int maxgain)
+{
+  int i, j, ncore;
+
+  queue->nnodes = 0;
+  queue->maxnodes = maxnodes;
+
+  queue->buckets = NULL;
+  queue->nodes = NULL;
+  queue->heap = NULL;
+  queue->locator = NULL;
+
+  if (maxgain > PLUS_GAINSPAN || maxnodes < 500)
+    queue->type = 2;
+  else
+    queue->type = 1;
+
+  if (queue->type == 1) {
+    queue->pgainspan = amin(PLUS_GAINSPAN, maxgain);
+    queue->ngainspan = amin(NEG_GAINSPAN, maxgain);
+
+    j = queue->ngainspan+queue->pgainspan+1;
+
+    ncore = 2 + (sizeof(ListNodeType)/sizeof(idxtype))*maxnodes + (sizeof(ListNodeType *)/sizeof(idxtype))*j;
+
+    if (WspaceAvail(ctrl) > ncore) {
+      queue->nodes = (ListNodeType *)idxwspacemalloc(ctrl, (sizeof(ListNodeType)/sizeof(idxtype))*maxnodes);
+      queue->buckets = (ListNodeType **)idxwspacemalloc(ctrl, (sizeof(ListNodeType *)/sizeof(idxtype))*j);
+      queue->mustfree = 0;
+    }
+    else { /* Not enough memory in the wspace, allocate it */
+      queue->nodes = (ListNodeType *)idxmalloc((sizeof(ListNodeType)/sizeof(idxtype))*maxnodes, "PQueueInit: queue->nodes");
+      queue->buckets = (ListNodeType **)idxmalloc((sizeof(ListNodeType *)/sizeof(idxtype))*j, "PQueueInit: queue->buckets");
+      queue->mustfree = 1;
+    }
+
+    for (i=0; i<maxnodes; i++) 
+      queue->nodes[i].id = i;
+
+    for (i=0; i<j; i++)
+      queue->buckets[i] = NULL;
+
+    queue->buckets += queue->ngainspan;  /* Advance buckets by the ngainspan proper indexing */
+    queue->maxgain = -queue->ngainspan;
+  }
+  else {
+    queue->heap = (KeyValueType *)idxwspacemalloc(ctrl, (sizeof(KeyValueType)/sizeof(idxtype))*maxnodes);
+    queue->locator = idxwspacemalloc(ctrl, maxnodes);
+    idxset(maxnodes, -1, queue->locator);
+  }
+
+}
+
+
+/*************************************************************************
+* This function resets the buckets
+**************************************************************************/
+void PQueueReset(PQueueType *queue)
+{
+  int i, j;
+  queue->nnodes = 0;
+
+  if (queue->type == 1) {
+    queue->maxgain = -queue->ngainspan;
+
+    j = queue->ngainspan+queue->pgainspan+1;
+    queue->buckets -= queue->ngainspan;  
+    for (i=0; i<j; i++)
+      queue->buckets[i] = NULL;
+    queue->buckets += queue->ngainspan;  
+  }
+  else {
+    idxset(queue->maxnodes, -1, queue->locator);
+  }
+
+}
+
+
+/*************************************************************************
+* This function frees the buckets
+**************************************************************************/
+void PQueueFree(CtrlType *ctrl, PQueueType *queue)
+{
+
+  if (queue->type == 1) {
+    if (queue->mustfree) {
+      queue->buckets -= queue->ngainspan;  
+      GKfree(&queue->nodes, &queue->buckets, LTERM);
+    } 
+    else {
+      idxwspacefree(ctrl, sizeof(ListNodeType *)*(queue->ngainspan+queue->pgainspan+1)/sizeof(idxtype));
+      idxwspacefree(ctrl, sizeof(ListNodeType)*queue->maxnodes/sizeof(idxtype));
+    }
+  }
+  else {
+    idxwspacefree(ctrl, sizeof(KeyValueType)*queue->maxnodes/sizeof(idxtype));
+    idxwspacefree(ctrl, queue->maxnodes);
+  }
+
+  queue->maxnodes = 0;
+}
+
+
+/*************************************************************************
+* This function returns the number of nodes in the queue
+**************************************************************************/
+int PQueueGetSize(PQueueType *queue)
+{
+  return queue->nnodes;
+}
+
+
+/*************************************************************************
+* This function adds a node of certain gain into a partition
+**************************************************************************/
+int PQueueInsert(PQueueType *queue, int node, int gain)
+{
+  int i, j, k;
+  idxtype *locator;
+  ListNodeType *newnode;
+  KeyValueType *heap;
+
+  if (queue->type == 1) {
+    ASSERT(gain >= -queue->ngainspan && gain <= queue->pgainspan);
+
+    /* Allocate and add the node */
+    queue->nnodes++;
+    newnode = queue->nodes + node;
+
+    /* Attach this node in the doubly-linked list */
+    newnode->next = queue->buckets[gain];
+    newnode->prev = NULL;
+    if (newnode->next != NULL)
+      newnode->next->prev = newnode;
+    queue->buckets[gain] = newnode;
+
+    if (queue->maxgain < gain)
+      queue->maxgain = gain;
+  }
+  else {
+    ASSERT(CheckHeap(queue));
+
+    heap = queue->heap;
+    locator = queue->locator;
+
+    ASSERT(locator[node] == -1);
+
+    i = queue->nnodes++;
+    while (i > 0) {
+      j = (i-1)/2;
+      if (heap[j].key < gain) {
+        heap[i] = heap[j];
+        locator[heap[i].val] = i;
+        i = j;
+      }
+      else 
+        break;
+    }
+    ASSERT(i >= 0);
+    heap[i].key = gain;
+    heap[i].val = node;
+    locator[node] = i;
+
+    ASSERT(CheckHeap(queue));
+  }
+
+  return 0;
+}
+
+
+/*************************************************************************
+* This function deletes a node from a partition and reinserts it with
+* an updated gain
+**************************************************************************/
+int PQueueDelete(PQueueType *queue, int node, int gain)
+{
+  int i, j, newgain, oldgain;
+  idxtype *locator;
+  ListNodeType *newnode, **buckets;
+  KeyValueType *heap;
+
+  if (queue->type == 1) {
+    ASSERT(gain >= -queue->ngainspan && gain <= queue->pgainspan);
+    ASSERT(queue->nnodes > 0);
+
+    buckets = queue->buckets;
+    queue->nnodes--;
+    newnode = queue->nodes+node;
+
+    /* Remove newnode from the doubly-linked list */
+    if (newnode->prev != NULL)
+      newnode->prev->next = newnode->next;
+    else
+      buckets[gain] = newnode->next;
+    if (newnode->next != NULL)
+      newnode->next->prev = newnode->prev;
+
+    if (buckets[gain] == NULL && gain == queue->maxgain) {
+      if (queue->nnodes == 0) 
+        queue->maxgain = -queue->ngainspan;
+      else 
+        for (; buckets[queue->maxgain]==NULL; queue->maxgain--);
+    }
+  }
+  else { /* Heap Priority Queue */
+    heap = queue->heap;
+    locator = queue->locator;
+
+    ASSERT(locator[node] != -1);
+    ASSERT(heap[locator[node]].val == node);
+
+    ASSERT(CheckHeap(queue));
+
+    i = locator[node];
+    locator[node] = -1;
+
+    if (--queue->nnodes > 0 && heap[queue->nnodes].val != node) {
+      node = heap[queue->nnodes].val;
+      newgain = heap[queue->nnodes].key;
+      oldgain = heap[i].key;
+
+      if (oldgain < newgain) { /* Filter-up */
+        while (i > 0) {
+          j = (i-1)>>1;
+          if (heap[j].key < newgain) {
+            heap[i] = heap[j];
+            locator[heap[i].val] = i;
+            i = j;
+          }
+          else 
+            break;
+        }
+      }
+      else { /* Filter down */
+        while ((j=2*i+1) < queue->nnodes) {
+          if (heap[j].key > newgain) {
+            if (j+1 < queue->nnodes && heap[j+1].key > heap[j].key)
+              j = j+1;
+            heap[i] = heap[j];
+            locator[heap[i].val] = i;
+            i = j;
+          }
+          else if (j+1 < queue->nnodes && heap[j+1].key > newgain) {
+            j = j+1;
+            heap[i] = heap[j];
+            locator[heap[i].val] = i;
+            i = j;
+          }
+          else
+            break;
+        }
+      }
+
+      heap[i].key = newgain;
+      heap[i].val = node;
+      locator[node] = i;
+    }
+
+    ASSERT(CheckHeap(queue));
+  }
+
+  return 0;
+}
+
+
+
+/*************************************************************************
+* This function deletes a node from a partition and reinserts it with
+* an updated gain
+**************************************************************************/
+int PQueueUpdate(PQueueType *queue, int node, int oldgain, int newgain)
+{
+  int i, j;
+  idxtype *locator;
+  ListNodeType *newnode;
+  KeyValueType *heap;
+
+  if (oldgain == newgain) 
+    return 0;
+
+  if (queue->type == 1) {
+    /* First delete the node and then insert it */
+    PQueueDelete(queue, node, oldgain);
+    return PQueueInsert(queue, node, newgain);
+  }
+  else { /* Heap Priority Queue */
+    heap = queue->heap;
+    locator = queue->locator;
+
+    ASSERT(locator[node] != -1);
+    ASSERT(heap[locator[node]].val == node);
+    ASSERT(heap[locator[node]].key == oldgain);
+    ASSERT(CheckHeap(queue));
+
+    i = locator[node];
+
+    if (oldgain < newgain) { /* Filter-up */
+      while (i > 0) {
+        j = (i-1)>>1;
+        if (heap[j].key < newgain) {
+          heap[i] = heap[j];
+          locator[heap[i].val] = i;
+          i = j;
+        }
+        else 
+          break;
+      }
+    }
+    else { /* Filter down */
+      while ((j=2*i+1) < queue->nnodes) {
+        if (heap[j].key > newgain) {
+          if (j+1 < queue->nnodes && heap[j+1].key > heap[j].key)
+            j = j+1;
+          heap[i] = heap[j];
+          locator[heap[i].val] = i;
+          i = j;
+        }
+        else if (j+1 < queue->nnodes && heap[j+1].key > newgain) {
+          j = j+1;
+          heap[i] = heap[j];
+          locator[heap[i].val] = i;
+          i = j;
+        }
+        else
+          break;
+      }
+    }
+
+    heap[i].key = newgain;
+    heap[i].val = node;
+    locator[node] = i;
+
+    ASSERT(CheckHeap(queue));
+  }
+
+  return 0;
+}
+
+
+
+/*************************************************************************
+* This function deletes a node from a partition and reinserts it with
+* an updated gain
+**************************************************************************/
+void PQueueUpdateUp(PQueueType *queue, int node, int oldgain, int newgain)
+{
+  int i, j;
+  idxtype *locator;
+  ListNodeType *newnode, **buckets;
+  KeyValueType *heap;
+
+  if (oldgain == newgain) 
+    return;
+
+  if (queue->type == 1) {
+    ASSERT(oldgain >= -queue->ngainspan && oldgain <= queue->pgainspan);
+    ASSERT(newgain >= -queue->ngainspan && newgain <= queue->pgainspan);
+    ASSERT(queue->nnodes > 0);
+
+    buckets = queue->buckets;
+    newnode = queue->nodes+node;
+
+    /* First delete the node */
+    if (newnode->prev != NULL)
+      newnode->prev->next = newnode->next;
+    else
+      buckets[oldgain] = newnode->next;
+    if (newnode->next != NULL)
+      newnode->next->prev = newnode->prev;
+
+    /* Attach this node in the doubly-linked list */
+    newnode->next = buckets[newgain];
+    newnode->prev = NULL;
+    if (newnode->next != NULL)
+      newnode->next->prev = newnode;
+    buckets[newgain] = newnode;
+
+    if (queue->maxgain < newgain)
+      queue->maxgain = newgain;
+  }
+  else { /* Heap Priority Queue */
+    heap = queue->heap;
+    locator = queue->locator;
+
+    ASSERT(locator[node] != -1);
+    ASSERT(heap[locator[node]].val == node);
+    ASSERT(heap[locator[node]].key == oldgain);
+    ASSERT(CheckHeap(queue));
+
+
+    /* Here we are just filtering up since the newgain is greater than the oldgain */
+    i = locator[node];
+    while (i > 0) {
+      j = (i-1)>>1;
+      if (heap[j].key < newgain) {
+        heap[i] = heap[j];
+        locator[heap[i].val] = i;
+        i = j;
+      }
+      else 
+        break;
+    }
+
+    heap[i].key = newgain;
+    heap[i].val = node;
+    locator[node] = i;
+
+    ASSERT(CheckHeap(queue));
+  }
+
+}
+
+
+/*************************************************************************
+* This function returns the vertex with the largest gain from a partition
+* and removes the node from the bucket list
+**************************************************************************/
+int PQueueGetMax(PQueueType *queue)
+{
+  int vtx, i, j, gain, node;
+  idxtype *locator;
+  ListNodeType *tptr;
+  KeyValueType *heap;
+
+  if (queue->nnodes == 0)
+    return -1;
+
+  queue->nnodes--;
+
+  if (queue->type == 1) {
+    tptr = queue->buckets[queue->maxgain];
+    queue->buckets[queue->maxgain] = tptr->next;
+    if (tptr->next != NULL) {
+      tptr->next->prev = NULL;
+    }
+    else {
+      if (queue->nnodes == 0) {
+        queue->maxgain = -queue->ngainspan;
+      }
+      else 
+        for (; queue->buckets[queue->maxgain]==NULL; queue->maxgain--);
+    }
+
+    return tptr->id;
+  }
+  else {
+    heap = queue->heap;
+    locator = queue->locator;
+
+    vtx = heap[0].val;
+    locator[vtx] = -1;
+
+    if ((i = queue->nnodes) > 0) {
+      gain = heap[i].key;
+      node = heap[i].val;
+      i = 0;
+      while ((j=2*i+1) < queue->nnodes) {
+        if (heap[j].key > gain) {
+          if (j+1 < queue->nnodes && heap[j+1].key > heap[j].key)
+            j = j+1;
+          heap[i] = heap[j];
+          locator[heap[i].val] = i;
+          i = j;
+        }
+        else if (j+1 < queue->nnodes && heap[j+1].key > gain) {
+          j = j+1;
+          heap[i] = heap[j];
+          locator[heap[i].val] = i;
+          i = j;
+        }
+        else
+          break;
+      }
+
+      heap[i].key = gain;
+      heap[i].val = node;
+      locator[node] = i;
+    }
+
+    ASSERT(CheckHeap(queue));
+    return vtx;
+  }
+}
+      
+
+/*************************************************************************
+* This function returns the vertex with the largest gain from a partition
+**************************************************************************/
+int PQueueSeeMax(PQueueType *queue)
+{
+  int vtx;
+
+  if (queue->nnodes == 0)
+    return -1;
+
+  if (queue->type == 1) 
+    vtx = queue->buckets[queue->maxgain]->id;
+  else
+    vtx = queue->heap[0].val;
+
+  return vtx;
+}
+      
+
+/*************************************************************************
+* This function returns the vertex with the largest gain from a partition
+**************************************************************************/
+int PQueueGetKey(PQueueType *queue)
+{
+  int key;
+
+  if (queue->nnodes == 0)
+    return -1;
+
+  if (queue->type == 1) 
+    key = queue->maxgain;
+  else
+    key = queue->heap[0].key;
+
+  return key;
+}
+      
+
+
+
+/*************************************************************************
+* This functions checks the consistency of the heap
+**************************************************************************/
+int CheckHeap(PQueueType *queue)
+{
+  int i, j, nnodes;
+  idxtype *locator;
+  KeyValueType *heap;
+
+  heap = queue->heap;
+  locator = queue->locator;
+  nnodes = queue->nnodes;
+
+  if (nnodes == 0)
+    return 1;
+
+  ASSERT(locator[heap[0].val] == 0);
+  for (i=1; i<nnodes; i++) {
+    ASSERTP(locator[heap[i].val] == i, ("%d %d %d %d\n", nnodes, i, heap[i].val, locator[heap[i].val])); 
+    ASSERTP(heap[i].key <= heap[(i-1)/2].key, ("%d %d %d %d %d\n", i, (i-1)/2, nnodes, heap[i].key, heap[(i-1)/2].key));
+  }
+  for (i=1; i<nnodes; i++)
+    ASSERT(heap[i].key <= heap[0].key);
+
+  for (j=i=0; i<queue->maxnodes; i++) {
+    if (locator[i] != -1)
+      j++;
+  }
+  ASSERTP(j == nnodes, ("%d %d\n", j, nnodes));
+
+  return 1;
+}
diff --git a/Metis/proto.h b/Metis/proto.h
new file mode 100644
index 0000000000..a82e7c9fa5
--- /dev/null
+++ b/Metis/proto.h
@@ -0,0 +1,505 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * proto.h
+ *
+ * This file contains header files
+ *
+ * Started 10/19/95
+ * George
+ *
+ * $Id: proto.h,v 1.1 2005-09-07 14:36:46 remacle Exp $
+ *
+ */
+
+/* balance.c */
+void Balance2Way(CtrlType *, GraphType *, int *, float);
+void Bnd2WayBalance(CtrlType *, GraphType *, int *);
+void General2WayBalance(CtrlType *, GraphType *, int *);
+
+/* bucketsort.c */
+void BucketSortKeysInc(int, int, idxtype *, idxtype *, idxtype *);
+
+/* ccgraph.c */
+void CreateCoarseGraph(CtrlType *, GraphType *, int, idxtype *, idxtype *);
+void CreateCoarseGraphNoMask(CtrlType *, GraphType *, int, idxtype *, idxtype *);
+void CreateCoarseGraph_NVW(CtrlType *, GraphType *, int, idxtype *, idxtype *);
+GraphType *SetUpCoarseGraph(GraphType *, int, int);
+void ReAdjustMemory(GraphType *, GraphType *, int);
+
+/* coarsen.c */
+GraphType *Coarsen2Way(CtrlType *, GraphType *);
+
+/* compress.c */
+void CompressGraph(CtrlType *, GraphType *, int, idxtype *, idxtype *, idxtype *, idxtype *);
+void PruneGraph(CtrlType *, GraphType *, int, idxtype *, idxtype *, idxtype *, float);
+
+/* debug.c */
+int ComputeCut(GraphType *, idxtype *);
+int CheckBnd(GraphType *);
+int CheckBnd2(GraphType *);
+int CheckNodeBnd(GraphType *, int);
+int CheckRInfo(RInfoType *);
+int CheckNodePartitionParams(GraphType *);
+int IsSeparable(GraphType *);
+
+/* estmem.c */
+void METIS_EstimateMemory(int *, idxtype *, idxtype *, int *, int *, int *);
+void EstimateCFraction(int, idxtype *, idxtype *, float *, float *);
+int ComputeCoarseGraphSize(int, idxtype *, idxtype *, int, idxtype *, idxtype *, idxtype *);
+
+/* fm.c */
+void FM_2WayEdgeRefine(CtrlType *, GraphType *, int *, int);
+
+/* fortran.c */
+void Change2CNumbering(int, idxtype *, idxtype *);
+void Change2FNumbering(int, idxtype *, idxtype *, idxtype *);
+void Change2FNumbering2(int, idxtype *, idxtype *);
+void Change2FNumberingOrder(int, idxtype *, idxtype *, idxtype *, idxtype *);
+void ChangeMesh2CNumbering(int, idxtype *);
+void ChangeMesh2FNumbering(int, idxtype *, int, idxtype *, idxtype *);
+void ChangeMesh2FNumbering2(int, idxtype *, int, int, idxtype *, idxtype *);
+
+/* frename.c */
+void METIS_PARTGRAPHRECURSIVE(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); 
+void metis_partgraphrecursive(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); 
+void metis_partgraphrecursive_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); 
+void metis_partgraphrecursive__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); 
+void METIS_WPARTGRAPHRECURSIVE(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); 
+void metis_wpartgraphrecursive(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); 
+void metis_wpartgraphrecursive_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); 
+void metis_wpartgraphrecursive__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); 
+void METIS_PARTGRAPHKWAY(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); 
+void metis_partgraphkway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); 
+void metis_partgraphkway_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); 
+void metis_partgraphkway__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); 
+void METIS_WPARTGRAPHKWAY(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); 
+void metis_wpartgraphkway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); 
+void metis_wpartgraphkway_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); 
+void metis_wpartgraphkway__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); 
+void METIS_EDGEND(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); 
+void metis_edgend(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); 
+void metis_edgend_(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); 
+void metis_edgend__(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); 
+void METIS_NODEND(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); 
+void metis_nodend(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); 
+void metis_nodend_(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); 
+void metis_nodend__(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); 
+void METIS_NODEWND(int *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); 
+void metis_nodewnd(int *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); 
+void metis_nodewnd_(int *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); 
+void metis_nodewnd__(int *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); 
+void METIS_PARTMESHNODAL(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *);
+void metis_partmeshnodal(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *);
+void metis_partmeshnodal_(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *);
+void metis_partmeshnodal__(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *);
+void METIS_PARTMESHDUAL(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *);
+void metis_partmeshdual(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *);
+void metis_partmeshdual_(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *);
+void metis_partmeshdual__(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *);
+void METIS_MESHTONODAL(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *);
+void metis_meshtonodal(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *);
+void metis_meshtonodal_(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *);
+void metis_meshtonodal__(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *);
+void METIS_MESHTODUAL(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *);
+void metis_meshtodual(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *);
+void metis_meshtodual_(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *);
+void metis_meshtodual__(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *);
+void METIS_ESTIMATEMEMORY(int *, idxtype *, idxtype *, int *, int *, int *);
+void metis_estimatememory(int *, idxtype *, idxtype *, int *, int *, int *);
+void metis_estimatememory_(int *, idxtype *, idxtype *, int *, int *, int *);
+void metis_estimatememory__(int *, idxtype *, idxtype *, int *, int *, int *);
+void METIS_MCPARTGRAPHRECURSIVE(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *);
+void metis_mcpartgraphrecursive(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *);
+void metis_mcpartgraphrecursive_(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *);
+void metis_mcpartgraphrecursive__(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *);
+void METIS_MCPARTGRAPHKWAY(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *);
+void metis_mcpartgraphkway(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *);
+void metis_mcpartgraphkway_(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *);
+void metis_mcpartgraphkway__(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *);
+void METIS_PARTGRAPHVKWAY(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *);
+void metis_partgraphvkway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *);
+void metis_partgraphvkway_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *);
+void metis_partgraphvkway__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *);
+void METIS_WPARTGRAPHVKWAY(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *);
+void metis_wpartgraphvkway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *);
+void metis_wpartgraphvkway_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *);
+void metis_wpartgraphvkway__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *);
+
+/* graph.c */
+void SetUpGraph(GraphType *, int, int, int, idxtype *, idxtype *, idxtype *, idxtype *, int);
+void SetUpGraphKway(GraphType *, int, idxtype *, idxtype *);
+void SetUpGraph2(GraphType *, int, int, idxtype *, idxtype *, float *, idxtype *);
+void VolSetUpGraph(GraphType *, int, int, int, idxtype *, idxtype *, idxtype *, idxtype *, int);
+void RandomizeGraph(GraphType *);
+int IsConnectedSubdomain(CtrlType *, GraphType *, int, int);
+int IsConnected(CtrlType *, GraphType *, int);
+int IsConnected2(GraphType *, int);
+int FindComponents(CtrlType *, GraphType *, idxtype *, idxtype *);
+
+/* initpart.c */
+void Init2WayPartition(CtrlType *, GraphType *, int *, float);
+void InitSeparator(CtrlType *, GraphType *, float);
+void GrowBisection(CtrlType *, GraphType *, int *, float);
+void GrowBisectionNode(CtrlType *, GraphType *, float);
+void RandomBisection(CtrlType *, GraphType *, int *, float);
+
+/* kmetis.c */
+void METIS_PartGraphKway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); 
+void METIS_WPartGraphKway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); 
+int MlevelKWayPartitioning(CtrlType *, GraphType *, int, idxtype *, float *, float);
+
+/* kvmetis.c */
+void METIS_PartGraphVKway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *);
+void METIS_WPartGraphVKway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *);
+int MlevelVolKWayPartitioning(CtrlType *, GraphType *, int, idxtype *, float *, float);
+
+/* kwayfm.c */
+void Random_KWayEdgeRefine(CtrlType *, GraphType *, int, float *, float, int, int);
+void Greedy_KWayEdgeRefine(CtrlType *, GraphType *, int, float *, float, int);
+void Greedy_KWayEdgeBalance(CtrlType *, GraphType *, int, float *, float, int);
+
+/* kwayrefine.c */
+void RefineKWay(CtrlType *, GraphType *, GraphType *, int, float *, float);
+void AllocateKWayPartitionMemory(CtrlType *, GraphType *, int);
+void ComputeKWayPartitionParams(CtrlType *, GraphType *, int);
+void ProjectKWayPartition(CtrlType *, GraphType *, int);
+int IsBalanced(idxtype *, int, float *, float);
+void ComputeKWayBoundary(CtrlType *, GraphType *, int);
+void ComputeKWayBalanceBoundary(CtrlType *, GraphType *, int);
+
+/* kwayvolfm.c */
+void Random_KWayVolRefine(CtrlType *, GraphType *, int, float *, float, int, int);
+void Random_KWayVolRefineMConn(CtrlType *, GraphType *, int, float *, float, int, int);
+void Greedy_KWayVolBalance(CtrlType *, GraphType *, int, float *, float, int);
+void Greedy_KWayVolBalanceMConn(CtrlType *, GraphType *, int, float *, float, int);
+void KWayVolUpdate(CtrlType *, GraphType *, int, int, int, idxtype *, idxtype *, idxtype *);
+void ComputeKWayVolume(GraphType *, int, idxtype *, idxtype *, idxtype *);
+int ComputeVolume(GraphType *, idxtype *);
+void CheckVolKWayPartitionParams(CtrlType *, GraphType *, int);
+void ComputeVolSubDomainGraph(GraphType *, int, idxtype *, idxtype *);
+void EliminateVolSubDomainEdges(CtrlType *, GraphType *, int, float *);
+void EliminateVolComponents(CtrlType *, GraphType *, int, float *, float);
+
+/* kwayvolrefine.c */
+void RefineVolKWay(CtrlType *, GraphType *, GraphType *, int, float *, float);
+void AllocateVolKWayPartitionMemory(CtrlType *, GraphType *, int);
+void ComputeVolKWayPartitionParams(CtrlType *, GraphType *, int);
+void ComputeKWayVolGains(CtrlType *, GraphType *, int);
+void ProjectVolKWayPartition(CtrlType *, GraphType *, int);
+void ComputeVolKWayBoundary(CtrlType *, GraphType *, int);
+void ComputeVolKWayBalanceBoundary(CtrlType *, GraphType *, int);
+
+/* match.c */
+void Match_RM(CtrlType *, GraphType *);
+void Match_RM_NVW(CtrlType *, GraphType *);
+void Match_HEM(CtrlType *, GraphType *);
+void Match_SHEM(CtrlType *, GraphType *);
+
+/* mbalance.c */
+void MocBalance2Way(CtrlType *, GraphType *, float *, float);
+void MocGeneral2WayBalance(CtrlType *, GraphType *, float *, float);
+
+/* mbalance2.c */
+void MocBalance2Way2(CtrlType *, GraphType *, float *, float *);
+void MocGeneral2WayBalance2(CtrlType *, GraphType *, float *, float *);
+void SelectQueue3(int, float *, float *, int *, int *, PQueueType [MAXNCON][2], float *);
+
+/* mcoarsen.c */
+GraphType *MCCoarsen2Way(CtrlType *, GraphType *);
+
+/* memory.c */
+void AllocateWorkSpace(CtrlType *, GraphType *, int);
+void FreeWorkSpace(CtrlType *, GraphType *);
+int WspaceAvail(CtrlType *);
+idxtype *idxwspacemalloc(CtrlType *, int);
+void idxwspacefree(CtrlType *, int);
+float *fwspacemalloc(CtrlType *, int);
+void fwspacefree(CtrlType *, int);
+GraphType *CreateGraph(void);
+void InitGraph(GraphType *);
+void FreeGraph(GraphType *);
+
+/* mesh.c */
+void METIS_MeshToDual(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *);
+void METIS_MeshToNodal(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *);
+void GENDUALMETIS(int, int, int, idxtype *, idxtype *, idxtype *adjncy);
+void TRINODALMETIS(int, int, idxtype *, idxtype *, idxtype *adjncy);
+void TETNODALMETIS(int, int, idxtype *, idxtype *, idxtype *adjncy);
+void HEXNODALMETIS(int, int, idxtype *, idxtype *, idxtype *adjncy);
+void QUADNODALMETIS(int, int, idxtype *, idxtype *, idxtype *adjncy);
+
+/* meshpart.c */
+void METIS_PartMeshNodal(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *);
+void METIS_PartMeshDual(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *);
+
+/* mfm.c */
+void MocFM_2WayEdgeRefine(CtrlType *, GraphType *, float *, int);
+void SelectQueue(int, float *, float *, int *, int *, PQueueType [MAXNCON][2]);
+int BetterBalance(int, float *, float *, float *);
+float Compute2WayHLoadImbalance(int, float *, float *);
+void Compute2WayHLoadImbalanceVec(int, float *, float *, float *);
+
+/* mfm2.c */
+void MocFM_2WayEdgeRefine2(CtrlType *, GraphType *, float *, float *, int);
+void SelectQueue2(int, float *, float *, int *, int *, PQueueType [MAXNCON][2], float *);
+int IsBetter2wayBalance(int, float *, float *, float *);
+
+/* mincover.o */
+void MinCover(idxtype *, idxtype *, int, int, idxtype *, int *);
+int MinCover_Augment(idxtype *, idxtype *, int, idxtype *, idxtype *, idxtype *, int);
+void MinCover_Decompose(idxtype *, idxtype *, int, int, idxtype *, idxtype *, int *);
+void MinCover_ColDFS(idxtype *, idxtype *, int, idxtype *, idxtype *, int);
+void MinCover_RowDFS(idxtype *, idxtype *, int, idxtype *, idxtype *, int);
+
+/* minitpart.c */
+void MocInit2WayPartition(CtrlType *, GraphType *, float *, float);
+void MocGrowBisection(CtrlType *, GraphType *, float *, float);
+void MocRandomBisection(CtrlType *, GraphType *, float *, float);
+void MocInit2WayBalance(CtrlType *, GraphType *, float *);
+int SelectQueueoneWay(int, float *, float *, int, PQueueType [MAXNCON][2]);
+
+/* minitpart2.c */
+void MocInit2WayPartition2(CtrlType *, GraphType *, float *, float *);
+void MocGrowBisection2(CtrlType *, GraphType *, float *, float *);
+void MocGrowBisectionNew2(CtrlType *, GraphType *, float *, float *);
+void MocInit2WayBalance2(CtrlType *, GraphType *, float *, float *);
+int SelectQueueOneWay2(int, float *, PQueueType [MAXNCON][2], float *);
+
+/* mkmetis.c */
+void METIS_mCPartGraphKway(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *);
+int MCMlevelKWayPartitioning(CtrlType *, GraphType *, int, idxtype *, float *);
+
+/* mkwayfmh.c */
+void MCRandom_KWayEdgeRefineHorizontal(CtrlType *, GraphType *, int, float *, int);
+void MCGreedy_KWayEdgeBalanceHorizontal(CtrlType *, GraphType *, int, float *, int);
+int AreAllHVwgtsBelow(int, float, float *, float, float *, float *);
+int AreAllHVwgtsAbove(int, float, float *, float, float *, float *);
+void ComputeHKWayLoadImbalance(int, int, float *, float *);
+int MocIsHBalanced(int, int, float *, float *);
+int IsHBalanceBetterFT(int, int, float *, float *, float *, float *);
+int IsHBalanceBetterTT(int, int, float *, float *, float *, float *);
+
+/* mkwayrefine.c */
+void MocRefineKWayHorizontal(CtrlType *, GraphType *, GraphType *, int, float *);
+void MocAllocateKWayPartitionMemory(CtrlType *, GraphType *, int);
+void MocComputeKWayPartitionParams(CtrlType *, GraphType *, int);
+void MocProjectKWayPartition(CtrlType *, GraphType *, int);
+void MocComputeKWayBalanceBoundary(CtrlType *, GraphType *, int);
+
+/* mmatch.c */
+void MCMatch_RM(CtrlType *, GraphType *);
+void MCMatch_HEM(CtrlType *, GraphType *);
+void MCMatch_SHEM(CtrlType *, GraphType *);
+void MCMatch_SHEBM(CtrlType *, GraphType *, int);
+void MCMatch_SBHEM(CtrlType *, GraphType *, int);
+float BetterVBalance(int, int, float *, float *, float *);
+int AreAllVwgtsBelowFast(int, float *, float *, float);
+
+/* mmd.c */
+void genmmd(int, idxtype *, idxtype *, idxtype *, idxtype *, int , idxtype *, idxtype *, idxtype *, idxtype *, int, int *);
+void mmdelm(int, idxtype *xadj, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, int, int);
+int  mmdint(int, idxtype *xadj, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *);
+void mmdnum(int, idxtype *, idxtype *, idxtype *);
+void mmdupd(int, int, idxtype *, idxtype *, int, int *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, int, int *tag);
+
+/* mpmetis.c */
+void METIS_mCPartGraphRecursive(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *);
+void METIS_mCHPartGraphRecursive(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *);
+void METIS_mCPartGraphRecursiveInternal(int *, int *, idxtype *, idxtype *, float *, idxtype *, int *, int *, int *, idxtype *);
+void METIS_mCHPartGraphRecursiveInternal(int *, int *, idxtype *, idxtype *, float *, idxtype *, int *, float *, int *, int *, idxtype *);
+int MCMlevelRecursiveBisection(CtrlType *, GraphType *, int, idxtype *, float, int);
+int MCHMlevelRecursiveBisection(CtrlType *, GraphType *, int, idxtype *, float *, int);
+void MCMlevelEdgeBisection(CtrlType *, GraphType *, float *, float);
+void MCHMlevelEdgeBisection(CtrlType *, GraphType *, float *, float *);
+
+/* mrefine.c */
+void MocRefine2Way(CtrlType *, GraphType *, GraphType *, float *, float);
+void MocAllocate2WayPartitionMemory(CtrlType *, GraphType *);
+void MocCompute2WayPartitionParams(CtrlType *, GraphType *);
+void MocProject2WayPartition(CtrlType *, GraphType *);
+
+/* mrefine2.c */
+void MocRefine2Way2(CtrlType *, GraphType *, GraphType *, float *, float *);
+
+/* mutil.c */
+int AreAllVwgtsBelow(int, float, float *, float, float *, float);
+int AreAnyVwgtsBelow(int, float, float *, float, float *, float);
+int AreAllVwgtsAbove(int, float, float *, float, float *, float);
+float ComputeLoadImbalance(int, int, float *, float *);
+int AreAllBelow(int, float *, float *);
+
+/* myqsort.c */
+void iidxsort(int, idxtype *);
+void iintsort(int, int *);
+void ikeysort(int, KeyValueType *);
+void ikeyvalsort(int, KeyValueType *);
+
+/* ometis.c */
+void METIS_EdgeND(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); 
+void METIS_NodeND(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); 
+void METIS_NodeWND(int *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); 
+void MlevelNestedDissection(CtrlType *, GraphType *, idxtype *, float, int);
+void MlevelNestedDissectionCC(CtrlType *, GraphType *, idxtype *, float, int);
+void MlevelNodeBisectionMultiple(CtrlType *, GraphType *, int *, float);
+void MlevelNodeBisection(CtrlType *, GraphType *, int *, float);
+void SplitGraphOrder(CtrlType *, GraphType *, GraphType *, GraphType *);
+void MMDOrder(CtrlType *, GraphType *, idxtype *, int);
+int SplitGraphOrderCC(CtrlType *, GraphType *, GraphType *, int, idxtype *, idxtype *);
+
+/* parmetis.c */
+void METIS_PartGraphKway2(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); 
+void METIS_WPartGraphKway2(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); 
+void METIS_NodeNDP(int, idxtype *, idxtype *, int, int *, idxtype *, idxtype *, idxtype *);
+void MlevelNestedDissectionP(CtrlType *, GraphType *, idxtype *, int, int, int, idxtype *);
+void METIS_NodeComputeSeparator(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *); 
+void METIS_EdgeComputeSeparator(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *); 
+
+/* pmetis.c */
+void METIS_PartGraphRecursive(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); 
+void METIS_WPartGraphRecursive(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); 
+int MlevelRecursiveBisection(CtrlType *, GraphType *, int, idxtype *, float *, float, int);
+void MlevelEdgeBisection(CtrlType *, GraphType *, int *, float);
+void SplitGraphPart(CtrlType *, GraphType *, GraphType *, GraphType *);
+void SetUpSplitGraph(GraphType *, GraphType *, int, int);
+
+/* pqueue.c */
+void PQueueInit(CtrlType *ctrl, PQueueType *, int, int);
+void PQueueReset(PQueueType *);
+void PQueueFree(CtrlType *ctrl, PQueueType *);
+int PQueueGetSize(PQueueType *);
+int PQueueInsert(PQueueType *, int, int);
+int PQueueDelete(PQueueType *, int, int);
+int PQueueUpdate(PQueueType *, int, int, int);
+void PQueueUpdateUp(PQueueType *, int, int, int);
+int PQueueGetMax(PQueueType *);
+int PQueueSeeMax(PQueueType *);
+int PQueueGetKey(PQueueType *);
+int CheckHeap(PQueueType *);
+
+/* refine.c */
+void Refine2Way(CtrlType *, GraphType *, GraphType *, int *, float ubfactor);
+void Allocate2WayPartitionMemory(CtrlType *, GraphType *);
+void Compute2WayPartitionParams(CtrlType *, GraphType *);
+void Project2WayPartition(CtrlType *, GraphType *);
+
+/* separator.c */
+void ConstructSeparator(CtrlType *, GraphType *, float);
+void ConstructMinCoverSeparator0(CtrlType *, GraphType *, float);
+void ConstructMinCoverSeparator(CtrlType *, GraphType *, float);
+
+/* sfm.c */
+void FM_2WayNodeRefine(CtrlType *, GraphType *, float, int);
+void FM_2WayNodeRefineEqWgt(CtrlType *, GraphType *, int);
+void FM_2WayNodeRefine_OneSided(CtrlType *, GraphType *, float, int);
+void FM_2WayNodeBalance(CtrlType *, GraphType *, float);
+int ComputeMaxNodeGain(int, idxtype *, idxtype *, idxtype *);
+
+/* srefine.c */
+void Refine2WayNode(CtrlType *, GraphType *, GraphType *, float);
+void Allocate2WayNodePartitionMemory(CtrlType *, GraphType *);
+void Compute2WayNodePartitionParams(CtrlType *, GraphType *);
+void Project2WayNodePartition(CtrlType *, GraphType *);
+
+/* stat.c */
+void ComputePartitionInfo(GraphType *, int, idxtype *);
+void ComputePartitionInfoBipartite(GraphType *, int, idxtype *);
+void ComputePartitionBalance(GraphType *, int, idxtype *, float *);
+float ComputeElementBalance(int, int, idxtype *);
+
+/* subdomains.c */
+void Random_KWayEdgeRefineMConn(CtrlType *, GraphType *, int, float *, float, int, int);
+void Greedy_KWayEdgeBalanceMConn(CtrlType *, GraphType *, int, float *, float, int);
+void PrintSubDomainGraph(GraphType *, int, idxtype *);
+void ComputeSubDomainGraph(GraphType *, int, idxtype *, idxtype *);
+void EliminateSubDomainEdges(CtrlType *, GraphType *, int, float *);
+void MoveGroupMConn(CtrlType *, GraphType *, idxtype *, idxtype *, int, int, int, idxtype *);
+void EliminateComponents(CtrlType *, GraphType *, int, float *, float);
+void MoveGroup(CtrlType *, GraphType *, int, int, int, idxtype *, idxtype *);
+
+/* timing.c */
+void InitTimers(CtrlType *);
+void PrintTimers(CtrlType *);
+double seconds(void);
+
+/* util.c */
+void errexit(char *,...);
+#ifndef DMALLOC
+int *imalloc(int, char *);
+idxtype *idxmalloc(int, char *);
+float *fmalloc(int, char *);
+int *ismalloc(int, int, char *);
+idxtype *idxsmalloc(int, idxtype, char *);
+void *GKmalloc(int, char *);
+#endif
+/*void GKfree(void **,...); */
+int *iset(int n, int val, int *x);
+idxtype *idxset(int n, idxtype val, idxtype *x);
+float *sset(int n, float val, float *x);
+int iamax(int, int *);
+int idxamax(int, idxtype *);
+int idxamax_strd(int, idxtype *, int);
+int samax(int, float *);
+int samax2(int, float *);
+int idxamin(int, idxtype *);
+int samin(int, float *);
+int idxsum(int, idxtype *);
+int idxsum_strd(int, idxtype *, int);
+void idxadd(int, idxtype *, idxtype *);
+int charsum(int, char *);
+int isum(int, int *);
+float ssum(int, float *);
+float ssum_strd(int n, float *x, int);
+void sscale(int n, float, float *x);
+float snorm2(int, float *);
+float sdot(int n, float *, float *);
+void saxpy(int, float, float *, int, float *, int);
+void RandomPermute(int, idxtype *, int);
+double drand48();
+void srand48(long);
+int ispow2(int);
+void InitRandom(int);
+//int log2(int);
+
+
+
+
+
+
+
+
+
+
+/***************************************************************
+* Programs Directory
+****************************************************************/
+
+/* io.c */
+void ReadGraph(GraphType *, char *, int *);
+void WritePartition(char *, idxtype *, int, int);
+void WriteMeshPartition(char *, int, int, idxtype *, int, idxtype *);
+void WritePermutation(char *, idxtype *, int);
+int CheckGraph(GraphType *);
+idxtype *ReadMesh(char *, int *, int *, int *);
+void WriteGraph(char *, int, idxtype *, idxtype *);
+
+/* smbfactor.c */
+void ComputeFillIn(GraphType *, idxtype *);
+idxtype ComputeFillIn2(GraphType *, idxtype *);
+int smbfct(int, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, int *, idxtype *, idxtype *, int *);
+
+
+/***************************************************************
+* Test Directory
+****************************************************************/
+void Test_PartGraph(int, idxtype *, idxtype *);
+int VerifyPart(int, idxtype *, idxtype *, idxtype *, idxtype *, int, int, idxtype *);
+int VerifyWPart(int, idxtype *, idxtype *, idxtype *, idxtype *, int, float *, int, idxtype *);
+void Test_PartGraphV(int, idxtype *, idxtype *);
+int VerifyPartV(int, idxtype *, idxtype *, idxtype *, idxtype *, int, int, idxtype *);
+int VerifyWPartV(int, idxtype *, idxtype *, idxtype *, idxtype *, int, float *, int, idxtype *);
+void Test_PartGraphmC(int, idxtype *, idxtype *);
+int VerifyPartmC(int, int, idxtype *, idxtype *, idxtype *, idxtype *, int, float *, int, idxtype *);
+void Test_ND(int, idxtype *, idxtype *);
+int VerifyND(int, idxtype *, idxtype *);
+
diff --git a/Metis/refine.c b/Metis/refine.c
new file mode 100644
index 0000000000..314ec21aaf
--- /dev/null
+++ b/Metis/refine.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * refine.c
+ *
+ * This file contains the driving routines for multilevel refinement
+ *
+ * Started 7/24/97
+ * George
+ *
+ * $Id: refine.c,v 1.1 2005-09-07 14:36:46 remacle Exp $
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function is the entry point of refinement
+**************************************************************************/
+void Refine2Way(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, int *tpwgts, float ubfactor)
+{
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr));
+
+  /* Compute the parameters of the coarsest graph */
+  Compute2WayPartitionParams(ctrl, graph);
+
+  for (;;) {
+    ASSERT(CheckBnd(graph));
+
+    IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr));
+    switch (ctrl->RType) {
+      case 1:
+        Balance2Way(ctrl, graph, tpwgts, ubfactor);
+        FM_2WayEdgeRefine(ctrl, graph, tpwgts, 8); 
+        break;
+      default:
+        errexit("Unknown refinement type: %d\n", ctrl->RType);
+    }
+    IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr));
+
+    if (graph == orggraph)
+      break;
+
+    graph = graph->finer;
+    IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr));
+    Project2WayPartition(ctrl, graph);
+    IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr));
+  }
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr));
+}
+
+
+/*************************************************************************
+* This function allocates memory for 2-way edge refinement
+**************************************************************************/
+void Allocate2WayPartitionMemory(CtrlType *ctrl, GraphType *graph)
+{
+  int nvtxs;
+
+  nvtxs = graph->nvtxs;
+
+  graph->rdata = idxmalloc(5*nvtxs+2, "Allocate2WayPartitionMemory: rdata");
+  graph->pwgts 		= graph->rdata;
+  graph->where		= graph->rdata + 2;
+  graph->id		= graph->rdata + nvtxs + 2;
+  graph->ed		= graph->rdata + 2*nvtxs + 2;
+  graph->bndptr		= graph->rdata + 3*nvtxs + 2;
+  graph->bndind		= graph->rdata + 4*nvtxs + 2;
+}
+
+
+/*************************************************************************
+* This function computes the initial id/ed 
+**************************************************************************/
+void Compute2WayPartitionParams(CtrlType *ctrl, GraphType *graph)
+{
+  int i, j, k, l, nvtxs, nbnd, mincut;
+  idxtype *xadj, *vwgt, *adjncy, *adjwgt, *pwgts;
+  idxtype *id, *ed, *where;
+  idxtype *bndptr, *bndind;
+  int me, other;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  vwgt = graph->vwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  where = graph->where;
+  pwgts = idxset(2, 0, graph->pwgts);
+  id = idxset(nvtxs, 0, graph->id);
+  ed = idxset(nvtxs, 0, graph->ed);
+  bndptr = idxset(nvtxs, -1, graph->bndptr);
+  bndind = graph->bndind;
+
+
+  /*------------------------------------------------------------
+  / Compute now the id/ed degrees
+  /------------------------------------------------------------*/
+  nbnd = mincut = 0;
+  for (i=0; i<nvtxs; i++) {
+    ASSERT(where[i] >= 0 && where[i] <= 1);
+    me = where[i];
+    pwgts[me] += vwgt[i];
+
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      if (me == where[adjncy[j]])
+        id[i] += adjwgt[j];
+      else
+        ed[i] += adjwgt[j];
+    }
+
+    if (ed[i] > 0 || xadj[i] == xadj[i+1]) {
+      mincut += ed[i];
+      bndptr[i] = nbnd;
+      bndind[nbnd++] = i;
+    }
+  }
+
+  graph->mincut = mincut/2;
+  graph->nbnd = nbnd;
+
+  ASSERT(pwgts[0]+pwgts[1] == idxsum(nvtxs, vwgt));
+}
+
+
+
+/*************************************************************************
+* This function projects a partition, and at the same time computes the
+* parameters for refinement.
+**************************************************************************/
+void Project2WayPartition(CtrlType *ctrl, GraphType *graph)
+{
+  int i, j, k, nvtxs, nbnd, me;
+  idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum;
+  idxtype *cmap, *where, *id, *ed, *bndptr, *bndind;
+  idxtype *cwhere, *cid, *ced, *cbndptr;
+  GraphType *cgraph;
+
+  cgraph = graph->coarser;
+  cwhere = cgraph->where;
+  cid = cgraph->id;
+  ced = cgraph->ed;
+  cbndptr = cgraph->bndptr;
+
+  nvtxs = graph->nvtxs;
+  cmap = graph->cmap;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+  adjwgtsum = graph->adjwgtsum;
+
+  Allocate2WayPartitionMemory(ctrl, graph);
+
+  where = graph->where;
+  id = idxset(nvtxs, 0, graph->id);
+  ed = idxset(nvtxs, 0, graph->ed);
+  bndptr = idxset(nvtxs, -1, graph->bndptr);
+  bndind = graph->bndind;
+
+
+  /* Go through and project partition and compute id/ed for the nodes */
+  for (i=0; i<nvtxs; i++) {
+    k = cmap[i];
+    where[i] = cwhere[k];
+    cmap[i] = cbndptr[k];
+  }
+
+  for (nbnd=0, i=0; i<nvtxs; i++) {
+    me = where[i];
+
+    id[i] = adjwgtsum[i];
+
+    if (xadj[i] == xadj[i+1]) {
+      bndptr[i] = nbnd;
+      bndind[nbnd++] = i;
+    }
+    else {
+      if (cmap[i] != -1) { /* If it is an interface node. Note that cmap[i] = cbndptr[cmap[i]] */
+        for (j=xadj[i]; j<xadj[i+1]; j++) {
+          if (me != where[adjncy[j]])
+            ed[i] += adjwgt[j];
+        }
+        id[i] -= ed[i];
+
+        if (ed[i] > 0 || xadj[i] == xadj[i+1]) {
+          bndptr[i] = nbnd;
+          bndind[nbnd++] = i;
+        }
+      }
+    }
+  }
+
+  graph->mincut = cgraph->mincut;
+  graph->nbnd = nbnd;
+  idxcopy(2, cgraph->pwgts, graph->pwgts);
+
+  FreeGraph(graph->coarser);
+  graph->coarser = NULL;
+
+}
+
diff --git a/Metis/rename.h b/Metis/rename.h
new file mode 100644
index 0000000000..74534511a4
--- /dev/null
+++ b/Metis/rename.h
@@ -0,0 +1,418 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * rename.h
+ *
+ * This file contains header files
+ *
+ * Started 10/2/97
+ * George
+ *
+ * $Id: rename.h,v 1.1 2005-09-07 14:36:46 remacle Exp $
+ *
+ */
+
+/* balance.c */
+#define Balance2Way			__Balance2Way
+#define Bnd2WayBalance			__Bnd2WayBalance
+#define General2WayBalance		__General2WayBalance
+
+
+/* bucketsort.c */
+#define BucketSortKeysInc		__BucketSortKeysInc
+
+
+/* ccgraph.c */
+#define CreateCoarseGraph		__CreateCoarseGraph
+#define CreateCoarseGraphNoMask		__CreateCoarseGraphNoMask
+#define CreateCoarseGraph_NVW 		__CreateCoarseGraph_NVW
+#define SetUpCoarseGraph		__SetUpCoarseGraph
+#define ReAdjustMemory			__ReAdjustMemory
+
+
+/* coarsen.c */
+#define Coarsen2Way			__Coarsen2Way
+
+
+/* compress.c */
+#define CompressGraph			__CompressGraph
+#define PruneGraph			__PruneGraph
+
+
+/* debug.c */
+#define ComputeCut			__ComputeCut
+#define CheckBnd			__CheckBnd
+#define CheckBnd2			__CheckBnd2
+#define CheckNodeBnd			__CheckNodeBnd
+#define CheckRInfo			__CheckRInfo
+#define CheckNodePartitionParams	__CheckNodePartitionParams
+#define IsSeparable			__IsSeparable
+
+
+/* estmem.c */
+#define EstimateCFraction		__EstimateCFraction
+#define ComputeCoarseGraphSize		__ComputeCoarseGraphSize
+
+
+/* fm.c */
+#define FM_2WayEdgeRefine		__FM_2WayEdgeRefine
+
+
+/* fortran.c */
+#define Change2CNumbering		__Change2CNumbering
+#define Change2FNumbering		__Change2FNumbering
+#define Change2FNumbering2		__Change2FNumbering2
+#define Change2FNumberingOrder		__Change2FNumberingOrder
+#define ChangeMesh2CNumbering		__ChangeMesh2CNumbering
+#define ChangeMesh2FNumbering		__ChangeMesh2FNumbering
+#define ChangeMesh2FNumbering2		__ChangeMesh2FNumbering2
+
+
+/* graph.c */
+#define SetUpGraph			__SetUpGraph
+#define SetUpGraphKway 			__SetUpGraphKway
+#define SetUpGraph2			__SetUpGraph2
+#define VolSetUpGraph			__VolSetUpGraph
+#define RandomizeGraph			__RandomizeGraph
+#define IsConnectedSubdomain		__IsConnectedSubdomain
+#define IsConnected			__IsConnected
+#define IsConnected2			__IsConnected2
+#define FindComponents			__FindComponents
+
+
+/* initpart.c */
+#define Init2WayPartition		__Init2WayPartition
+#define InitSeparator			__InitSeparator
+#define GrowBisection			__GrowBisection
+#define GrowBisectionNode		__GrowBisectionNode
+#define RandomBisection			__RandomBisection
+
+
+/* kmetis.c */
+#define MlevelKWayPartitioning		__MlevelKWayPartitioning
+
+
+/* kvmetis.c */
+#define MlevelVolKWayPartitioning	__MlevelVolKWayPartitioning
+
+
+/* kwayfm.c */
+#define Random_KWayEdgeRefine		__Random_KWayEdgeRefine
+#define Greedy_KWayEdgeRefine		__Greedy_KWayEdgeRefine
+#define Greedy_KWayEdgeBalance		__Greedy_KWayEdgeBalance
+
+
+/* kwayrefine.c */
+#define RefineKWay			__RefineKWay
+#define AllocateKWayPartitionMemory	__AllocateKWayPartitionMemory
+#define ComputeKWayPartitionParams	__ComputeKWayPartitionParams
+#define ProjectKWayPartition		__ProjectKWayPartition
+#define IsBalanced			__IsBalanced
+#define ComputeKWayBoundary		__ComputeKWayBoundary
+#define ComputeKWayBalanceBoundary	__ComputeKWayBalanceBoundary
+
+
+/* kwayvolfm.c */
+#define Random_KWayVolRefine		__Random_KWayVolRefine
+#define Random_KWayVolRefineMConn	__Random_KWayVolRefineMConn
+#define Greedy_KWayVolBalance		__Greedy_KWayVolBalance
+#define Greedy_KWayVolBalanceMConn	__Greedy_KWayVolBalanceMConn
+#define KWayVolUpdate			__KWayVolUpdate
+#define ComputeKWayVolume		__ComputeKWayVolume
+#define ComputeVolume			__ComputeVolume
+#define CheckVolKWayPartitionParams	__CheckVolKWayPartitionParams
+#define ComputeVolSubDomainGraph	__ComputeVolSubDomainGraph
+#define EliminateVolSubDomainEdges	__EliminateVolSubDomainEdges
+
+
+/* kwayvolrefine.c */
+#define RefineVolKWay			__RefineVolKWay
+#define AllocateVolKWayPartitionMemory	__AllocateVolKWayPartitionMemory
+#define ComputeVolKWayPartitionParams	__ComputeVolKWayPartitionParams
+#define ComputeKWayVolGains		__ComputeKWayVolGains
+#define ProjectVolKWayPartition		__ProjectVolKWayPartition
+#define ComputeVolKWayBoundary		__ComputeVolKWayBoundary
+#define ComputeVolKWayBalanceBoundary	__ComputeVolKWayBalanceBoundary
+
+
+/* match.c */
+#define Match_RM			__Match_RM
+#define Match_RM_NVW			__Match_RM_NVW
+#define Match_HEM			__Match_HEM
+#define Match_SHEM			__Match_SHEM
+
+
+/* mbalance.c */
+#define MocBalance2Way			__MocBalance2Way
+#define MocGeneral2WayBalance		__MocGeneral2WayBalance
+
+
+/* mbalance2.c */
+#define MocBalance2Way2			__MocBalance2Way2
+#define MocGeneral2WayBalance2		__MocGeneral2WayBalance2
+#define SelectQueue3			__SelectQueue3
+
+
+/* mcoarsen.c */
+#define MCCoarsen2Way			__MCCoarsen2Way
+
+
+/* memory.c */
+#define AllocateWorkSpace		__AllocateWorkSpace
+#define FreeWorkSpace			__FreeWorkSpace
+#define WspaceAvail			__WspaceAvail
+#define idxwspacemalloc			__idxwspacemalloc
+#define idxwspacefree			__idxwspacefree
+#define fwspacemalloc			__fwspacemalloc
+#define CreateGraph			__CreateGraph
+#define InitGraph			__InitGraph
+#define FreeGraph			__FreeGraph
+
+
+/* mesh.c */
+#define TRIDUALMETIS			__TRIDUALMETIS
+#define TETDUALMETIS			__TETDUALMETIS
+#define HEXDUALMETIS			__HEXDUALMETIS
+#define TRINODALMETIS			__TRINODALMETIS
+#define TETNODALMETIS			__TETNODALMETIS
+#define HEXNODALMETIS			__HEXNODALMETIS
+
+
+/* mfm.c */
+#define MocFM_2WayEdgeRefine		__MocFM_2WayEdgeRefine
+#define SelectQueue			__SelectQueue
+#define BetterBalance			__BetterBalance
+#define Compute2WayHLoadImbalance	__Compute2WayHLoadImbalance
+#define Compute2WayHLoadImbalanceVec	__Compute2WayHLoadImbalanceVec
+
+
+/* mfm2.c */
+#define MocFM_2WayEdgeRefine2		__MocFM_2WayEdgeRefine2
+#define SelectQueue2			__SelectQueue2
+#define IsBetter2wayBalance		__IsBetter2wayBalance
+
+
+/* mincover.c */
+#define MinCover			__MinCover
+#define MinCover_Augment		__MinCover_Augment
+#define MinCover_Decompose		__MinCover_Decompose
+#define MinCover_ColDFS			__MinCover_ColDFS
+#define MinCover_RowDFS			__MinCover_RowDFS
+
+
+/* minitpart.c */
+#define MocInit2WayPartition		__MocInit2WayPartition
+#define MocGrowBisection		__MocGrowBisection
+#define MocRandomBisection		__MocRandomBisection
+#define MocInit2WayBalance		__MocInit2WayBalance
+#define SelectQueueoneWay		__SelectQueueoneWay
+
+
+/* minitpart2.c */
+#define MocInit2WayPartition2		__MocInit2WayPartition2
+#define MocGrowBisection2		__MocGrowBisection2
+#define MocGrowBisectionNew2		__MocGrowBisectionNew2
+#define MocInit2WayBalance2		__MocInit2WayBalance2
+#define SelectQueueOneWay2		__SelectQueueOneWay2
+
+
+/* mkmetis.c */
+#define MCMlevelKWayPartitioning	__MCMlevelKWayPartitioning
+
+
+/* mkwayfmh.c */
+#define MCRandom_KWayEdgeRefineHorizontal	__MCRandom_KWayEdgeRefineHorizontal
+#define MCGreedy_KWayEdgeBalanceHorizontal	__MCGreedy_KWayEdgeBalanceHorizontal
+#define AreAllHVwgtsBelow			__AreAllHVwgtsBelow
+#define AreAllHVwgtsAbove			__AreAllHVwgtsAbove
+#define ComputeHKWayLoadImbalance		__ComputeHKWayLoadImbalance
+#define MocIsHBalanced				__MocIsHBalanced
+#define IsHBalanceBetterFT			__IsHBalanceBetterFT
+#define IsHBalanceBetterTT			__IsHBalanceBetterTT
+
+
+/* mkwayrefine.c */
+#define MocRefineKWayHorizontal		__MocRefineKWayHorizontal
+#define MocAllocateKWayPartitionMemory	__MocAllocateKWayPartitionMemory
+#define MocComputeKWayPartitionParams	__MocComputeKWayPartitionParams
+#define MocProjectKWayPartition		__MocProjectKWayPartition
+#define MocComputeKWayBalanceBoundary	__MocComputeKWayBalanceBoundary
+
+
+/* mmatch.c */
+#define MCMatch_RM			__MCMatch_RM
+#define MCMatch_HEM			__MCMatch_HEM
+#define MCMatch_SHEM			__MCMatch_SHEM
+#define MCMatch_SHEBM			__MCMatch_SHEBM
+#define MCMatch_SBHEM			__MCMatch_SBHEM
+#define BetterVBalance			__BetterVBalance
+#define AreAllVwgtsBelowFast		__AreAllVwgtsBelowFast
+
+
+/* mmd.c */
+#define genmmd				__genmmd
+#define mmdelm				__mmdelm
+#define mmdint				__mmdint
+#define mmdnum				__mmdnum
+#define mmdupd				__mmdupd
+
+
+/* mpmetis.c */
+#define MCMlevelRecursiveBisection	__MCMlevelRecursiveBisection
+#define MCHMlevelRecursiveBisection	__MCHMlevelRecursiveBisection
+#define MCMlevelEdgeBisection		__MCMlevelEdgeBisection
+#define MCHMlevelEdgeBisection		__MCHMlevelEdgeBisection
+
+
+/* mrefine.c */
+#define MocRefine2Way			__MocRefine2Way
+#define MocAllocate2WayPartitionMemory	__MocAllocate2WayPartitionMemory
+#define MocCompute2WayPartitionParams	__MocCompute2WayPartitionParams
+#define MocProject2WayPartition		__MocProject2WayPartition
+
+
+/* mrefine2.c */
+#define MocRefine2Way2			__MocRefine2Way2
+
+
+/* mutil.c */
+#define AreAllVwgtsBelow		__AreAllVwgtsBelow
+#define AreAnyVwgtsBelow		__AreAnyVwgtsBelow
+#define AreAllVwgtsAbove		__AreAllVwgtsAbove
+#define ComputeLoadImbalance		__ComputeLoadImbalance
+#define AreAllBelow			__AreAllBelow
+
+
+/* myqsort.c */
+#define iidxsort			__iidxsort
+#define iintsort			__iintsort
+#define ikeysort			__ikeysort
+#define ikeyvalsort			__ikeyvalsort
+
+
+/* ometis.c */
+#define MlevelNestedDissection		__MlevelNestedDissection
+#define MlevelNestedDissectionCC	__MlevelNestedDissectionCC
+#define MlevelNodeBisectionMultiple	__MlevelNodeBisectionMultiple
+#define MlevelNodeBisection		__MlevelNodeBisection
+#define SplitGraphOrder			__SplitGraphOrder
+#define MMDOrder			__MMDOrder
+#define SplitGraphOrderCC		__SplitGraphOrderCC
+
+
+/* parmetis.c */
+#define MlevelNestedDissectionP		__MlevelNestedDissectionP
+
+
+/* pmetis.c */
+#define MlevelRecursiveBisection	__MlevelRecursiveBisection
+#define MlevelEdgeBisection		__MlevelEdgeBisection
+#define SplitGraphPart			__SplitGraphPart
+#define SetUpSplitGraph			__SetUpSplitGraph
+
+
+/* pqueue.c */
+#define PQueueInit			__PQueueInit
+#define PQueueReset			__PQueueReset
+#define PQueueFree			__PQueueFree
+#define PQueueInsert			__PQueueInsert
+#define PQueueDelete			__PQueueDelete
+#define PQueueUpdate			__PQueueUpdate
+#define PQueueUpdateUp			__PQueueUpdateUp
+#define PQueueGetMax			__PQueueGetMax
+#define PQueueSeeMax			__PQueueSeeMax
+#define CheckHeap			__CheckHeap
+
+
+/* refine.c */
+#define Refine2Way			__Refine2Way
+#define Allocate2WayPartitionMemory	__Allocate2WayPartitionMemory
+#define Compute2WayPartitionParams	__Compute2WayPartitionParams
+#define Project2WayPartition		__Project2WayPartition
+
+
+/* separator.c */
+#define ConstructSeparator		__ConstructSeparator
+#define ConstructMinCoverSeparator0	__ConstructMinCoverSeparator0
+#define ConstructMinCoverSeparator	__ConstructMinCoverSeparator
+
+
+/* sfm.c */
+#define FM_2WayNodeRefine		__FM_2WayNodeRefine
+#define FM_2WayNodeRefineEqWgt		__FM_2WayNodeRefineEqWgt
+#define FM_2WayNodeRefine_OneSided	__FM_2WayNodeRefine_OneSided
+#define FM_2WayNodeBalance		__FM_2WayNodeBalance
+#define ComputeMaxNodeGain		__ComputeMaxNodeGain
+
+
+/* srefine.c */
+#define Refine2WayNode			__Refine2WayNode
+#define Allocate2WayNodePartitionMemory	__Allocate2WayNodePartitionMemory
+#define Compute2WayNodePartitionParams	__Compute2WayNodePartitionParams
+#define Project2WayNodePartition	__Project2WayNodePartition
+
+
+/* stat.c */
+#define ComputePartitionInfo		__ComputePartitionInfo
+#define ComputePartitionBalance		__ComputePartitionBalance
+#define ComputeElementBalance		__ComputeElementBalance
+
+
+/* subdomains.c */
+#define Random_KWayEdgeRefineMConn	__Random_KWayEdgeRefineMConn
+#define Greedy_KWayEdgeBalanceMConn	__Greedy_KWayEdgeBalanceMConn
+#define PrintSubDomainGraph		__PrintSubDomainGraph
+#define ComputeSubDomainGraph		__ComputeSubDomainGraph
+#define EliminateSubDomainEdges		__EliminateSubDomainEdges
+#define MoveGroupMConn			__MoveGroupMConn
+#define EliminateComponents		__EliminateComponents
+#define MoveGroup			__MoveGroup
+
+
+/* timing.c */
+#define InitTimers			__InitTimers
+#define PrintTimers			__PrintTimers
+#define seconds				__seconds
+
+
+/* util.c */
+#define errexit				__errexit
+#define GKfree				__GKfree
+#ifndef DMALLOC
+#define imalloc				__imalloc
+#define idxmalloc			__idxmalloc
+#define fmalloc				__fmalloc
+#define ismalloc			__ismalloc
+#define idxsmalloc			__idxsmalloc
+#define GKmalloc			__GKmalloc
+#endif
+#define iset				__iset
+#define idxset				__idxset
+#define sset				__sset
+#define iamax				__iamax
+#define idxamax				__idxamax
+#define idxamax_strd			__idxamax_strd
+#define samax				__samax
+#define samax2				__samax2
+#define idxamin				__idxamin
+#define samin				__samin
+#define idxsum				__idxsum
+#define idxsum_strd			__idxsum_strd
+#define idxadd				__idxadd
+#define charsum				__charsum
+#define isum				__isum
+#define ssum				__ssum
+#define ssum_strd			__ssum_strd
+#define sscale				__sscale
+#define snorm2				__snorm2
+#define sdot				__sdot
+#define saxpy				__saxpy
+#define RandomPermute			__RandomPermute
+#define ispow2				__ispow2
+#define InitRandom			__InitRandom
+#define log2				__log2
+
+
+
+
+
diff --git a/Metis/separator.c b/Metis/separator.c
new file mode 100644
index 0000000000..cbabeacb7f
--- /dev/null
+++ b/Metis/separator.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * separator.c
+ *
+ * This file contains code for separator extraction
+ *
+ * Started 8/1/97
+ * George
+ *
+ * $Id: separator.c,v 1.1 2005-09-07 14:36:46 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+/*************************************************************************
+* This function takes a bisection and constructs a minimum weight vertex 
+* separator out of it. It uses the node-based separator refinement for it.
+**************************************************************************/
+void ConstructSeparator(CtrlType *ctrl, GraphType *graph, float ubfactor)
+{
+  int i, j, k, nvtxs, nbnd;
+  idxtype *xadj, *where, *bndind;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  nbnd = graph->nbnd;
+  bndind = graph->bndind;
+
+  where = idxcopy(nvtxs, graph->where, idxwspacemalloc(ctrl, nvtxs));
+
+  /* Put the nodes in the boundary into the separator */
+  for (i=0; i<nbnd; i++) {
+    j = bndind[i];
+    if (xadj[j+1]-xadj[j] > 0)  /* Ignore islands */
+      where[j] = 2;
+  }
+
+  GKfree(&graph->rdata, LTERM);
+  Allocate2WayNodePartitionMemory(ctrl, graph);
+  idxcopy(nvtxs, where, graph->where);
+  idxwspacefree(ctrl, nvtxs);
+
+  ASSERT(IsSeparable(graph));
+
+  Compute2WayNodePartitionParams(ctrl, graph);
+
+  ASSERT(CheckNodePartitionParams(graph));
+
+  FM_2WayNodeRefine(ctrl, graph, ubfactor, 8); 
+
+  ASSERT(IsSeparable(graph));
+}
+
+
+
+/*************************************************************************
+* This function takes a bisection and constructs a minimum weight vertex 
+* separator out of it. It uses an unweighted minimum-cover algorithm
+* followed by node-based separator refinement.
+**************************************************************************/
+void ConstructMinCoverSeparator0(CtrlType *ctrl, GraphType *graph, float ubfactor)
+{
+  int i, ii, j, jj, k, l, nvtxs, nbnd, bnvtxs[3], bnedges[2], csize;
+  idxtype *xadj, *adjncy, *bxadj, *badjncy;
+  idxtype *where, *bndind, *bndptr, *vmap, *ivmap, *cover;
+
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+
+  nbnd = graph->nbnd;
+  bndind = graph->bndind;
+  bndptr = graph->bndptr;
+  where = graph->where;
+
+  vmap = idxwspacemalloc(ctrl, nvtxs);
+  ivmap = idxwspacemalloc(ctrl, nbnd);
+  cover = idxwspacemalloc(ctrl, nbnd);
+
+  if (nbnd > 0) {
+    /* Go through the boundary and determine the sizes of the bipartite graph */
+    bnvtxs[0] = bnvtxs[1] = bnedges[0] = bnedges[1] = 0;
+    for (i=0; i<nbnd; i++) {
+      j = bndind[i];
+      k = where[j];
+      if (xadj[j+1]-xadj[j] > 0) {
+        bnvtxs[k]++;
+        bnedges[k] += xadj[j+1]-xadj[j];
+      }
+    }
+
+    bnvtxs[2] = bnvtxs[0]+bnvtxs[1];
+    bnvtxs[1] = bnvtxs[0];
+    bnvtxs[0] = 0;
+
+    bxadj = idxmalloc(bnvtxs[2]+1, "ConstructMinCoverSeparator: bxadj");
+    badjncy = idxmalloc(bnedges[0]+bnedges[1]+1, "ConstructMinCoverSeparator: badjncy");
+
+    /* Construct the ivmap and vmap */
+    ASSERT(idxset(nvtxs, -1, vmap) == vmap);
+    for (i=0; i<nbnd; i++) {
+      j = bndind[i];
+      k = where[j];
+      if (xadj[j+1]-xadj[j] > 0) {
+        vmap[j] = bnvtxs[k];
+        ivmap[bnvtxs[k]++] = j;
+      }
+    }
+
+    /* OK, go through and put the vertices of each part starting from 0 */
+    bnvtxs[1] = bnvtxs[0];
+    bnvtxs[0] = 0;
+    bxadj[0] = l = 0;
+    for (k=0; k<2; k++) {
+      for (ii=0; ii<nbnd; ii++) {
+        i = bndind[ii];
+        if (where[i] == k && xadj[i] < xadj[i+1]) {
+          for (j=xadj[i]; j<xadj[i+1]; j++) {
+            jj = adjncy[j];
+            if (where[jj] != k) {
+              ASSERT(bndptr[jj] != -1); 
+              ASSERTP(vmap[jj] != -1, ("%d %d %d\n", jj, vmap[jj], graph->bndptr[jj]));
+              badjncy[l++] = vmap[jj];
+            }
+          }
+          bxadj[++bnvtxs[k]] = l;
+        }
+      }
+    }
+
+    ASSERT(l <= bnedges[0]+bnedges[1]);
+
+    MinCover(bxadj, badjncy, bnvtxs[0], bnvtxs[1], cover, &csize);
+
+    IFSET(ctrl->dbglvl, DBG_SEPINFO,
+      printf("Nvtxs: %6d, [%5d %5d], Cut: %6d, SS: [%6d %6d], Cover: %6d\n", nvtxs, graph->pwgts[0], graph->pwgts[1], graph->mincut, bnvtxs[0], bnvtxs[1]-bnvtxs[0], csize));
+
+    for (i=0; i<csize; i++) {
+      j = ivmap[cover[i]];
+      where[j] = 2;
+    }
+
+    GKfree(&bxadj, &badjncy, LTERM);
+
+    for (i=0; i<nbnd; i++)
+      bndptr[bndind[i]] = -1;
+    for (nbnd=i=0; i<nvtxs; i++) {
+      if (where[i] == 2) {
+        bndind[nbnd] = i;
+        bndptr[i] = nbnd++;
+      }
+    }
+  }
+  else {
+    IFSET(ctrl->dbglvl, DBG_SEPINFO,
+      printf("Nvtxs: %6d, [%5d %5d], Cut: %6d, SS: [%6d %6d], Cover: %6d\n", nvtxs, graph->pwgts[0], graph->pwgts[1], graph->mincut, 0, 0, 0));
+  }
+
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, graph->nbnd);
+  idxwspacefree(ctrl, graph->nbnd);
+  graph->nbnd = nbnd;
+
+
+  ASSERT(IsSeparable(graph));
+}
+
+
+
+/*************************************************************************
+* This function takes a bisection and constructs a minimum weight vertex 
+* separator out of it. It uses an unweighted minimum-cover algorithm
+* followed by node-based separator refinement.
+**************************************************************************/
+void ConstructMinCoverSeparator(CtrlType *ctrl, GraphType *graph, float ubfactor)
+{
+  int i, ii, j, jj, k, l, nvtxs, nbnd, bnvtxs[3], bnedges[2], csize;
+  idxtype *xadj, *adjncy, *bxadj, *badjncy;
+  idxtype *where, *bndind, *bndptr, *vmap, *ivmap, *cover;
+
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+
+  nbnd = graph->nbnd;
+  bndind = graph->bndind;
+  bndptr = graph->bndptr;
+  where = graph->where;
+
+  vmap = idxwspacemalloc(ctrl, nvtxs);
+  ivmap = idxwspacemalloc(ctrl, nbnd);
+  cover = idxwspacemalloc(ctrl, nbnd);
+
+  if (nbnd > 0) {
+    /* Go through the boundary and determine the sizes of the bipartite graph */
+    bnvtxs[0] = bnvtxs[1] = bnedges[0] = bnedges[1] = 0;
+    for (i=0; i<nbnd; i++) {
+      j = bndind[i];
+      k = where[j];
+      if (xadj[j+1]-xadj[j] > 0) {
+        bnvtxs[k]++;
+        bnedges[k] += xadj[j+1]-xadj[j];
+      }
+    }
+
+    bnvtxs[2] = bnvtxs[0]+bnvtxs[1];
+    bnvtxs[1] = bnvtxs[0];
+    bnvtxs[0] = 0;
+
+    bxadj = idxmalloc(bnvtxs[2]+1, "ConstructMinCoverSeparator: bxadj");
+    badjncy = idxmalloc(bnedges[0]+bnedges[1]+1, "ConstructMinCoverSeparator: badjncy");
+
+    /* Construct the ivmap and vmap */
+    ASSERT(idxset(nvtxs, -1, vmap) == vmap);
+    for (i=0; i<nbnd; i++) {
+      j = bndind[i];
+      k = where[j];
+      if (xadj[j+1]-xadj[j] > 0) {
+        vmap[j] = bnvtxs[k];
+        ivmap[bnvtxs[k]++] = j;
+      }
+    }
+
+    /* OK, go through and put the vertices of each part starting from 0 */
+    bnvtxs[1] = bnvtxs[0];
+    bnvtxs[0] = 0;
+    bxadj[0] = l = 0;
+    for (k=0; k<2; k++) {
+      for (ii=0; ii<nbnd; ii++) {
+        i = bndind[ii];
+        if (where[i] == k && xadj[i] < xadj[i+1]) {
+          for (j=xadj[i]; j<xadj[i+1]; j++) {
+            jj = adjncy[j];
+            if (where[jj] != k) {
+              ASSERT(bndptr[jj] != -1); 
+              ASSERTP(vmap[jj] != -1, ("%d %d %d\n", jj, vmap[jj], graph->bndptr[jj]));
+              badjncy[l++] = vmap[jj];
+            }
+          }
+          bxadj[++bnvtxs[k]] = l;
+        }
+      }
+    }
+
+    ASSERT(l <= bnedges[0]+bnedges[1]);
+
+    MinCover(bxadj, badjncy, bnvtxs[0], bnvtxs[1], cover, &csize);
+
+    IFSET(ctrl->dbglvl, DBG_SEPINFO,
+      printf("Nvtxs: %6d, [%5d %5d], Cut: %6d, SS: [%6d %6d], Cover: %6d\n", nvtxs, graph->pwgts[0], graph->pwgts[1], graph->mincut, bnvtxs[0], bnvtxs[1]-bnvtxs[0], csize));
+
+    for (i=0; i<csize; i++) {
+      j = ivmap[cover[i]];
+      where[j] = 2;
+    }
+
+    GKfree(&bxadj, &badjncy, LTERM);
+  }
+  else {
+    IFSET(ctrl->dbglvl, DBG_SEPINFO,
+      printf("Nvtxs: %6d, [%5d %5d], Cut: %6d, SS: [%6d %6d], Cover: %6d\n", nvtxs, graph->pwgts[0], graph->pwgts[1], graph->mincut, 0, 0, 0));
+  }
+
+  /* Prepare to refine the vertex separator */
+  idxcopy(nvtxs, graph->where, vmap);
+  GKfree(&graph->rdata, LTERM);
+
+  Allocate2WayNodePartitionMemory(ctrl, graph);
+  idxcopy(nvtxs, vmap, graph->where);
+  idxwspacefree(ctrl, nvtxs+2*graph->nbnd);
+
+  Compute2WayNodePartitionParams(ctrl, graph);
+
+  ASSERT(CheckNodePartitionParams(graph));
+
+  FM_2WayNodeRefine_OneSided(ctrl, graph, ubfactor, 6); 
+
+  ASSERT(IsSeparable(graph));
+}
+
diff --git a/Metis/sfm.c b/Metis/sfm.c
new file mode 100644
index 0000000000..28f1acb874
--- /dev/null
+++ b/Metis/sfm.c
@@ -0,0 +1,1069 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * sfm.c
+ *
+ * This file contains code that implementes an FM-based separator refinement
+ *
+ * Started 8/1/97
+ * George
+ *
+ * $Id: sfm.c,v 1.1 2005-09-07 14:36:46 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function performs a node-based FM refinement 
+**************************************************************************/
+void FM_2WayNodeRefine(CtrlType *ctrl, GraphType *graph, float ubfactor, int npasses)
+{
+  int i, ii, j, k, jj, kk, nvtxs, nbnd, nswaps, nmind;
+  idxtype *xadj, *vwgt, *adjncy, *where, *pwgts, *edegrees, *bndind, *bndptr;
+  idxtype *mptr, *mind, *moved, *swaps, *perm;
+  PQueueType parts[2]; 
+  NRInfoType *rinfo;
+  int higain, oldgain, mincut, initcut, mincutorder;	
+  int pass, to, other, limit;
+  int badmaxpwgt, mindiff, newdiff;
+  int u[2], g[2];
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  vwgt = graph->vwgt;
+
+  bndind = graph->bndind;
+  bndptr = graph->bndptr;
+  where = graph->where;
+  pwgts = graph->pwgts;
+  rinfo = graph->nrinfo;
+
+
+  i = ComputeMaxNodeGain(nvtxs, xadj, adjncy, vwgt);
+  PQueueInit(ctrl, &parts[0], nvtxs, i);
+  PQueueInit(ctrl, &parts[1], nvtxs, i);
+
+  moved = idxwspacemalloc(ctrl, nvtxs);
+  swaps = idxwspacemalloc(ctrl, nvtxs);
+  mptr = idxwspacemalloc(ctrl, nvtxs+1);
+  mind = idxwspacemalloc(ctrl, nvtxs);
+  perm = idxwspacemalloc(ctrl, nvtxs);
+
+  IFSET(ctrl->dbglvl, DBG_REFINE,
+    printf("Partitions: [%6d %6d] Nv-Nb[%6d %6d]. ISep: %6d\n", pwgts[0], pwgts[1], graph->nvtxs, graph->nbnd, graph->mincut));
+
+  badmaxpwgt = (int)(ubfactor*(pwgts[0]+pwgts[1]+pwgts[2])/2);
+
+  for (pass=0; pass<npasses; pass++) {
+    idxset(nvtxs, -1, moved);
+    PQueueReset(&parts[0]);
+    PQueueReset(&parts[1]);
+
+    mincutorder = -1;
+    initcut = mincut = graph->mincut;
+    nbnd = graph->nbnd;
+
+    RandomPermute(nbnd, perm, 1);
+    for (ii=0; ii<nbnd; ii++) {
+      i = bndind[perm[ii]];
+      ASSERT(where[i] == 2);
+      PQueueInsert(&parts[0], i, vwgt[i]-rinfo[i].edegrees[1]);
+      PQueueInsert(&parts[1], i, vwgt[i]-rinfo[i].edegrees[0]);
+    }
+
+    ASSERT(CheckNodeBnd(graph, nbnd));
+    ASSERT(CheckNodePartitionParams(graph));
+
+    limit = (ctrl->oflags&OFLAG_COMPRESS ? amin(5*nbnd, 400) : amin(2*nbnd, 300));
+
+    /******************************************************
+    * Get into the FM loop
+    *******************************************************/
+    mptr[0] = nmind = 0;
+    mindiff = abs(pwgts[0]-pwgts[1]);
+    to = (pwgts[0] < pwgts[1] ? 0 : 1);
+    for (nswaps=0; nswaps<nvtxs; nswaps++) {
+      u[0] = PQueueSeeMax(&parts[0]);  
+      u[1] = PQueueSeeMax(&parts[1]);
+      if (u[0] != -1 && u[1] != -1) {
+        g[0] = vwgt[u[0]]-rinfo[u[0]].edegrees[1];
+        g[1] = vwgt[u[1]]-rinfo[u[1]].edegrees[0];
+
+        to = (g[0] > g[1] ? 0 : (g[0] < g[1] ? 1 : pass%2)); 
+        /* to = (g[0] > g[1] ? 0 : (g[0] < g[1] ? 1 : (pwgts[0] < pwgts[1] ? 0 : 1))); */
+
+        if (pwgts[to]+vwgt[u[to]] > badmaxpwgt) 
+          to = (to+1)%2;
+      }
+      else if (u[0] == -1 && u[1] == -1) {
+        break;
+      }
+      else if (u[0] != -1 && pwgts[0]+vwgt[u[0]] <= badmaxpwgt) {
+        to = 0;
+      }
+      else if (u[1] != -1 && pwgts[1]+vwgt[u[1]] <= badmaxpwgt) {
+        to = 1;
+      }
+      else
+        break;
+
+      other = (to+1)%2;
+
+      higain = PQueueGetMax(&parts[to]);
+      if (moved[higain] == -1) /* Delete if it was in the separator originally */
+        PQueueDelete(&parts[other], higain, vwgt[higain]-rinfo[higain].edegrees[to]);
+
+      ASSERT(bndptr[higain] != -1);
+
+      pwgts[2] -= (vwgt[higain]-rinfo[higain].edegrees[other]);
+
+      newdiff = abs(pwgts[to]+vwgt[higain] - (pwgts[other]-rinfo[higain].edegrees[other]));
+      if (pwgts[2] < mincut || (pwgts[2] == mincut && newdiff < mindiff)) {
+        mincut = pwgts[2];
+        mincutorder = nswaps;
+        mindiff = newdiff;
+      }
+      else {
+        if (nswaps - mincutorder > limit) {
+          pwgts[2] += (vwgt[higain]-rinfo[higain].edegrees[other]);
+          break; /* No further improvement, break out */
+        }
+      }
+
+      BNDDelete(nbnd, bndind, bndptr, higain);
+      pwgts[to] += vwgt[higain];
+      where[higain] = to;
+      moved[higain] = nswaps;
+      swaps[nswaps] = higain;  
+
+
+      /**********************************************************
+      * Update the degrees of the affected nodes
+      ***********************************************************/
+      for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+        k = adjncy[j];
+        if (where[k] == 2) { /* For the in-separator vertices modify their edegree[to] */
+          oldgain = vwgt[k]-rinfo[k].edegrees[to];
+          rinfo[k].edegrees[to] += vwgt[higain];
+          if (moved[k] == -1 || moved[k] == -(2+other))
+            PQueueUpdate(&parts[other], k, oldgain, oldgain-vwgt[higain]);
+        }
+        else if (where[k] == other) { /* This vertex is pulled into the separator */
+          ASSERTP(bndptr[k] == -1, ("%d %d %d\n", k, bndptr[k], where[k]));
+          BNDInsert(nbnd, bndind, bndptr, k);
+
+          mind[nmind++] = k;  /* Keep track for rollback */
+          where[k] = 2;
+          pwgts[other] -= vwgt[k];
+
+          edegrees = rinfo[k].edegrees;
+          edegrees[0] = edegrees[1] = 0;
+          for (jj=xadj[k]; jj<xadj[k+1]; jj++) {
+            kk = adjncy[jj];
+            if (where[kk] != 2) 
+              edegrees[where[kk]] += vwgt[kk];
+            else {
+              oldgain = vwgt[kk]-rinfo[kk].edegrees[other];
+              rinfo[kk].edegrees[other] -= vwgt[k];
+              if (moved[kk] == -1 || moved[kk] == -(2+to))
+                PQueueUpdate(&parts[to], kk, oldgain, oldgain+vwgt[k]);
+            }
+          }
+
+          /* Insert the new vertex into the priority queue. Only one side! */
+          if (moved[k] == -1) {
+            PQueueInsert(&parts[to], k, vwgt[k]-edegrees[other]);
+            moved[k] = -(2+to);
+          }
+        }
+      }
+      mptr[nswaps+1] = nmind;
+
+      IFSET(ctrl->dbglvl, DBG_MOVEINFO,
+            printf("Moved %6d to %3d, Gain: %5d [%5d] [%4d %4d] \t[%5d %5d %5d]\n", higain, to, g[to], g[other], vwgt[u[to]], vwgt[u[other]], pwgts[0], pwgts[1], pwgts[2]));
+
+    }
+
+
+    /****************************************************************
+    * Roll back computation 
+    *****************************************************************/
+    for (nswaps--; nswaps>mincutorder; nswaps--) {
+      higain = swaps[nswaps];
+
+      ASSERT(CheckNodePartitionParams(graph));
+
+      to = where[higain];
+      other = (to+1)%2;
+      INC_DEC(pwgts[2], pwgts[to], vwgt[higain]);
+      where[higain] = 2;
+      BNDInsert(nbnd, bndind, bndptr, higain);
+
+      edegrees = rinfo[higain].edegrees;
+      edegrees[0] = edegrees[1] = 0;
+      for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+        k = adjncy[j];
+        if (where[k] == 2) 
+          rinfo[k].edegrees[to] -= vwgt[higain];
+        else
+          edegrees[where[k]] += vwgt[k];
+      }
+
+      /* Push nodes out of the separator */
+      for (j=mptr[nswaps]; j<mptr[nswaps+1]; j++) {
+        k = mind[j];
+        ASSERT(where[k] == 2);
+        where[k] = other;
+        INC_DEC(pwgts[other], pwgts[2], vwgt[k]);
+        BNDDelete(nbnd, bndind, bndptr, k);
+        for (jj=xadj[k]; jj<xadj[k+1]; jj++) {
+          kk = adjncy[jj];
+          if (where[kk] == 2) 
+            rinfo[kk].edegrees[other] += vwgt[k];
+        }
+      }
+    }
+
+    ASSERT(mincut == pwgts[2]);
+
+    IFSET(ctrl->dbglvl, DBG_REFINE,
+      printf("\tMinimum sep: %6d at %5d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, mincutorder, pwgts[0], pwgts[1], nbnd));
+
+    graph->mincut = mincut;
+    graph->nbnd = nbnd;
+
+    if (mincutorder == -1 || mincut >= initcut)
+      break;
+  }
+
+  PQueueFree(ctrl, &parts[0]);
+  PQueueFree(ctrl, &parts[1]);
+
+  idxwspacefree(ctrl, nvtxs+1);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+/*************************************************************************
+* This function performs a node-based FM refinement 
+**************************************************************************/
+void FM_2WayNodeRefine2(CtrlType *ctrl, GraphType *graph, float ubfactor, int npasses)
+{
+  int i, ii, j, k, jj, kk, nvtxs, nbnd, nswaps, nmind;
+  idxtype *xadj, *vwgt, *adjncy, *where, *pwgts, *edegrees, *bndind, *bndptr;
+  idxtype *mptr, *mind, *moved, *swaps, *perm;
+  PQueueType parts[2]; 
+  NRInfoType *rinfo;
+  int higain, oldgain, mincut, initcut, mincutorder;	
+  int pass, to, other, limit;
+  int badmaxpwgt, mindiff, newdiff;
+  int u[2], g[2];
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  vwgt = graph->vwgt;
+
+  bndind = graph->bndind;
+  bndptr = graph->bndptr;
+  where = graph->where;
+  pwgts = graph->pwgts;
+  rinfo = graph->nrinfo;
+
+
+  i = ComputeMaxNodeGain(nvtxs, xadj, adjncy, vwgt);
+  PQueueInit(ctrl, &parts[0], nvtxs, i);
+  PQueueInit(ctrl, &parts[1], nvtxs, i);
+
+  moved = idxwspacemalloc(ctrl, nvtxs);
+  swaps = idxwspacemalloc(ctrl, nvtxs);
+  mptr = idxwspacemalloc(ctrl, nvtxs+1);
+  mind = idxwspacemalloc(ctrl, nvtxs);
+  perm = idxwspacemalloc(ctrl, nvtxs);
+
+  IFSET(ctrl->dbglvl, DBG_REFINE,
+    printf("Partitions: [%6d %6d] Nv-Nb[%6d %6d]. ISep: %6d\n", pwgts[0], pwgts[1], graph->nvtxs, graph->nbnd, graph->mincut));
+
+  badmaxpwgt = (int)(ubfactor*(pwgts[0]+pwgts[1]+pwgts[2])/2);
+
+  for (pass=0; pass<npasses; pass++) {
+    idxset(nvtxs, -1, moved);
+    PQueueReset(&parts[0]);
+    PQueueReset(&parts[1]);
+
+    mincutorder = -1;
+    initcut = mincut = graph->mincut;
+    nbnd = graph->nbnd;
+
+    RandomPermute(nbnd, perm, 1);
+    for (ii=0; ii<nbnd; ii++) {
+      i = bndind[perm[ii]];
+      ASSERT(where[i] == 2);
+      PQueueInsert(&parts[0], i, vwgt[i]-rinfo[i].edegrees[1]);
+      PQueueInsert(&parts[1], i, vwgt[i]-rinfo[i].edegrees[0]);
+    }
+
+    ASSERT(CheckNodeBnd(graph, nbnd));
+    ASSERT(CheckNodePartitionParams(graph));
+
+    limit = (ctrl->oflags&OFLAG_COMPRESS ? amin(5*nbnd, 400) : amin(2*nbnd, 300));
+
+    /******************************************************
+    * Get into the FM loop
+    *******************************************************/
+    mptr[0] = nmind = 0;
+    mindiff = abs(pwgts[0]-pwgts[1]);
+    to = (pwgts[0] < pwgts[1] ? 0 : 1);
+    for (nswaps=0; nswaps<nvtxs; nswaps++) {
+      badmaxpwgt = (int)(ubfactor*(pwgts[0]+pwgts[1]+pwgts[2]/2)/2);
+
+      u[0] = PQueueSeeMax(&parts[0]);  
+      u[1] = PQueueSeeMax(&parts[1]);
+      if (u[0] != -1 && u[1] != -1) {
+        g[0] = vwgt[u[0]]-rinfo[u[0]].edegrees[1];
+        g[1] = vwgt[u[1]]-rinfo[u[1]].edegrees[0];
+
+        to = (g[0] > g[1] ? 0 : (g[0] < g[1] ? 1 : pass%2)); 
+        /* to = (g[0] > g[1] ? 0 : (g[0] < g[1] ? 1 : (pwgts[0] < pwgts[1] ? 0 : 1))); */
+
+        if (pwgts[to]+vwgt[u[to]] > badmaxpwgt) 
+          to = (to+1)%2;
+      }
+      else if (u[0] == -1 && u[1] == -1) {
+        break;
+      }
+      else if (u[0] != -1 && pwgts[0]+vwgt[u[0]] <= badmaxpwgt) {
+        to = 0;
+      }
+      else if (u[1] != -1 && pwgts[1]+vwgt[u[1]] <= badmaxpwgt) {
+        to = 1;
+      }
+      else
+        break;
+
+      other = (to+1)%2;
+
+      higain = PQueueGetMax(&parts[to]);
+      if (moved[higain] == -1) /* Delete if it was in the separator originally */
+        PQueueDelete(&parts[other], higain, vwgt[higain]-rinfo[higain].edegrees[to]);
+
+      ASSERT(bndptr[higain] != -1);
+
+      pwgts[2] -= (vwgt[higain]-rinfo[higain].edegrees[other]);
+
+      newdiff = abs(pwgts[to]+vwgt[higain] - (pwgts[other]-rinfo[higain].edegrees[other]));
+      if (pwgts[2] < mincut || (pwgts[2] == mincut && newdiff < mindiff)) {
+        mincut = pwgts[2];
+        mincutorder = nswaps;
+        mindiff = newdiff;
+      }
+      else {
+        if (nswaps - mincutorder > limit) {
+          pwgts[2] += (vwgt[higain]-rinfo[higain].edegrees[other]);
+          break; /* No further improvement, break out */
+        }
+      }
+
+      BNDDelete(nbnd, bndind, bndptr, higain);
+      pwgts[to] += vwgt[higain];
+      where[higain] = to;
+      moved[higain] = nswaps;
+      swaps[nswaps] = higain;  
+
+
+      /**********************************************************
+      * Update the degrees of the affected nodes
+      ***********************************************************/
+      for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+        k = adjncy[j];
+        if (where[k] == 2) { /* For the in-separator vertices modify their edegree[to] */
+          oldgain = vwgt[k]-rinfo[k].edegrees[to];
+          rinfo[k].edegrees[to] += vwgt[higain];
+          if (moved[k] == -1 || moved[k] == -(2+other))
+            PQueueUpdate(&parts[other], k, oldgain, oldgain-vwgt[higain]);
+        }
+        else if (where[k] == other) { /* This vertex is pulled into the separator */
+          ASSERTP(bndptr[k] == -1, ("%d %d %d\n", k, bndptr[k], where[k]));
+          BNDInsert(nbnd, bndind, bndptr, k);
+
+          mind[nmind++] = k;  /* Keep track for rollback */
+          where[k] = 2;
+          pwgts[other] -= vwgt[k];
+
+          edegrees = rinfo[k].edegrees;
+          edegrees[0] = edegrees[1] = 0;
+          for (jj=xadj[k]; jj<xadj[k+1]; jj++) {
+            kk = adjncy[jj];
+            if (where[kk] != 2) 
+              edegrees[where[kk]] += vwgt[kk];
+            else {
+              oldgain = vwgt[kk]-rinfo[kk].edegrees[other];
+              rinfo[kk].edegrees[other] -= vwgt[k];
+              if (moved[kk] == -1 || moved[kk] == -(2+to))
+                PQueueUpdate(&parts[to], kk, oldgain, oldgain+vwgt[k]);
+            }
+          }
+
+          /* Insert the new vertex into the priority queue. Only one side! */
+          if (moved[k] == -1) {
+            PQueueInsert(&parts[to], k, vwgt[k]-edegrees[other]);
+            moved[k] = -(2+to);
+          }
+        }
+      }
+      mptr[nswaps+1] = nmind;
+
+      IFSET(ctrl->dbglvl, DBG_MOVEINFO,
+            printf("Moved %6d to %3d, Gain: %5d [%5d] [%4d %4d] \t[%5d %5d %5d]\n", higain, to, g[to], g[other], vwgt[u[to]], vwgt[u[other]], pwgts[0], pwgts[1], pwgts[2]));
+
+    }
+
+
+    /****************************************************************
+    * Roll back computation 
+    *****************************************************************/
+    for (nswaps--; nswaps>mincutorder; nswaps--) {
+      higain = swaps[nswaps];
+
+      ASSERT(CheckNodePartitionParams(graph));
+
+      to = where[higain];
+      other = (to+1)%2;
+      INC_DEC(pwgts[2], pwgts[to], vwgt[higain]);
+      where[higain] = 2;
+      BNDInsert(nbnd, bndind, bndptr, higain);
+
+      edegrees = rinfo[higain].edegrees;
+      edegrees[0] = edegrees[1] = 0;
+      for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+        k = adjncy[j];
+        if (where[k] == 2) 
+          rinfo[k].edegrees[to] -= vwgt[higain];
+        else
+          edegrees[where[k]] += vwgt[k];
+      }
+
+      /* Push nodes out of the separator */
+      for (j=mptr[nswaps]; j<mptr[nswaps+1]; j++) {
+        k = mind[j];
+        ASSERT(where[k] == 2);
+        where[k] = other;
+        INC_DEC(pwgts[other], pwgts[2], vwgt[k]);
+        BNDDelete(nbnd, bndind, bndptr, k);
+        for (jj=xadj[k]; jj<xadj[k+1]; jj++) {
+          kk = adjncy[jj];
+          if (where[kk] == 2) 
+            rinfo[kk].edegrees[other] += vwgt[k];
+        }
+      }
+    }
+
+    ASSERT(mincut == pwgts[2]);
+
+    IFSET(ctrl->dbglvl, DBG_REFINE,
+      printf("\tMinimum sep: %6d at %5d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, mincutorder, pwgts[0], pwgts[1], nbnd));
+
+    graph->mincut = mincut;
+    graph->nbnd = nbnd;
+
+    if (mincutorder == -1 || mincut >= initcut)
+      break;
+  }
+
+  PQueueFree(ctrl, &parts[0]);
+  PQueueFree(ctrl, &parts[1]);
+
+  idxwspacefree(ctrl, nvtxs+1);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+/*************************************************************************
+* This function performs a node-based FM refinement 
+**************************************************************************/
+void FM_2WayNodeRefineEqWgt(CtrlType *ctrl, GraphType *graph, int npasses)
+{
+  int i, ii, j, k, jj, kk, nvtxs, nbnd, nswaps, nmind;
+  idxtype *xadj, *vwgt, *adjncy, *where, *pwgts, *edegrees, *bndind, *bndptr;
+  idxtype *mptr, *mind, *moved, *swaps, *perm;
+  PQueueType parts[2]; 
+  NRInfoType *rinfo;
+  int higain, oldgain, mincut, initcut, mincutorder;	
+  int pass, to, other, limit;
+  int mindiff, newdiff;
+  int u[2], g[2];
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  vwgt = graph->vwgt;
+
+  bndind = graph->bndind;
+  bndptr = graph->bndptr;
+  where = graph->where;
+  pwgts = graph->pwgts;
+  rinfo = graph->nrinfo;
+
+
+  i = ComputeMaxNodeGain(nvtxs, xadj, adjncy, vwgt);
+  PQueueInit(ctrl, &parts[0], nvtxs, i);
+  PQueueInit(ctrl, &parts[1], nvtxs, i);
+
+  moved = idxwspacemalloc(ctrl, nvtxs);
+  swaps = idxwspacemalloc(ctrl, nvtxs);
+  mptr = idxwspacemalloc(ctrl, nvtxs+1);
+  mind = idxwspacemalloc(ctrl, nvtxs);
+  perm = idxwspacemalloc(ctrl, nvtxs);
+
+  IFSET(ctrl->dbglvl, DBG_REFINE,
+    printf("Partitions: [%6d %6d] Nv-Nb[%6d %6d]. ISep: %6d\n", pwgts[0], pwgts[1], graph->nvtxs, graph->nbnd, graph->mincut));
+
+  for (pass=0; pass<npasses; pass++) {
+    idxset(nvtxs, -1, moved);
+    PQueueReset(&parts[0]);
+    PQueueReset(&parts[1]);
+
+    mincutorder = -1;
+    initcut = mincut = graph->mincut;
+    nbnd = graph->nbnd;
+
+    RandomPermute(nbnd, perm, 1);
+    for (ii=0; ii<nbnd; ii++) {
+      i = bndind[perm[ii]];
+      ASSERT(where[i] == 2);
+      PQueueInsert(&parts[0], i, vwgt[i]-rinfo[i].edegrees[1]);
+      PQueueInsert(&parts[1], i, vwgt[i]-rinfo[i].edegrees[0]);
+    }
+
+    ASSERT(CheckNodeBnd(graph, nbnd));
+    ASSERT(CheckNodePartitionParams(graph));
+
+    limit = (ctrl->oflags&OFLAG_COMPRESS ? amin(5*nbnd, 400) : amin(2*nbnd, 300));
+
+    /******************************************************
+    * Get into the FM loop
+    *******************************************************/
+    mptr[0] = nmind = 0;
+    mindiff = abs(pwgts[0]-pwgts[1]);
+    to = (pwgts[0] < pwgts[1] ? 0 : 1);
+    for (nswaps=0; nswaps<nvtxs; nswaps++) {
+      to = (pwgts[0] < pwgts[1] ? 0 : 1);
+
+      if (pwgts[0] == pwgts[1]) {
+        u[0] = PQueueSeeMax(&parts[0]);  
+        u[1] = PQueueSeeMax(&parts[1]);
+        if (u[0] != -1 && u[1] != -1) {
+          g[0] = vwgt[u[0]]-rinfo[u[0]].edegrees[1];
+          g[1] = vwgt[u[1]]-rinfo[u[1]].edegrees[0];
+
+          to = (g[0] > g[1] ? 0 : (g[0] < g[1] ? 1 : pass%2)); 
+        }
+      }
+      other = (to+1)%2;
+
+      if ((higain = PQueueGetMax(&parts[to])) == -1)
+        break;
+
+      if (moved[higain] == -1) /* Delete if it was in the separator originally */
+        PQueueDelete(&parts[other], higain, vwgt[higain]-rinfo[higain].edegrees[to]);
+
+      ASSERT(bndptr[higain] != -1);
+
+      pwgts[2] -= (vwgt[higain]-rinfo[higain].edegrees[other]);
+
+      newdiff = abs(pwgts[to]+vwgt[higain] - (pwgts[other]-rinfo[higain].edegrees[other]));
+      if (pwgts[2] < mincut || (pwgts[2] == mincut && newdiff < mindiff)) {
+        mincut = pwgts[2];
+        mincutorder = nswaps;
+        mindiff = newdiff;
+      }
+      else {
+        if (nswaps - mincutorder > limit) {
+          pwgts[2] += (vwgt[higain]-rinfo[higain].edegrees[other]);
+          break; /* No further improvement, break out */
+        }
+      }
+
+      BNDDelete(nbnd, bndind, bndptr, higain);
+      pwgts[to] += vwgt[higain];
+      where[higain] = to;
+      moved[higain] = nswaps;
+      swaps[nswaps] = higain;  
+
+
+      /**********************************************************
+      * Update the degrees of the affected nodes
+      ***********************************************************/
+      for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+        k = adjncy[j];
+        if (where[k] == 2) { /* For the in-separator vertices modify their edegree[to] */
+          oldgain = vwgt[k]-rinfo[k].edegrees[to];
+          rinfo[k].edegrees[to] += vwgt[higain];
+          if (moved[k] == -1 || moved[k] == -(2+other))
+            PQueueUpdate(&parts[other], k, oldgain, oldgain-vwgt[higain]);
+        }
+        else if (where[k] == other) { /* This vertex is pulled into the separator */
+          ASSERTP(bndptr[k] == -1, ("%d %d %d\n", k, bndptr[k], where[k]));
+          BNDInsert(nbnd, bndind, bndptr, k);
+
+          mind[nmind++] = k;  /* Keep track for rollback */
+          where[k] = 2;
+          pwgts[other] -= vwgt[k];
+
+          edegrees = rinfo[k].edegrees;
+          edegrees[0] = edegrees[1] = 0;
+          for (jj=xadj[k]; jj<xadj[k+1]; jj++) {
+            kk = adjncy[jj];
+            if (where[kk] != 2) 
+              edegrees[where[kk]] += vwgt[kk];
+            else {
+              oldgain = vwgt[kk]-rinfo[kk].edegrees[other];
+              rinfo[kk].edegrees[other] -= vwgt[k];
+              if (moved[kk] == -1 || moved[kk] == -(2+to))
+                PQueueUpdate(&parts[to], kk, oldgain, oldgain+vwgt[k]);
+            }
+          }
+
+          /* Insert the new vertex into the priority queue. Only one side! */
+          if (moved[k] == -1) {
+            PQueueInsert(&parts[to], k, vwgt[k]-edegrees[other]);
+            moved[k] = -(2+to);
+          }
+        }
+      }
+      mptr[nswaps+1] = nmind;
+
+      IFSET(ctrl->dbglvl, DBG_MOVEINFO,
+            printf("Moved %6d to %3d, Gain: %5d [%5d] [%4d %4d] \t[%5d %5d %5d]\n", higain, to, g[to], g[other], vwgt[u[to]], vwgt[u[other]], pwgts[0], pwgts[1], pwgts[2]));
+
+    }
+
+
+    /****************************************************************
+    * Roll back computation 
+    *****************************************************************/
+    for (nswaps--; nswaps>mincutorder; nswaps--) {
+      higain = swaps[nswaps];
+
+      ASSERT(CheckNodePartitionParams(graph));
+
+      to = where[higain];
+      other = (to+1)%2;
+      INC_DEC(pwgts[2], pwgts[to], vwgt[higain]);
+      where[higain] = 2;
+      BNDInsert(nbnd, bndind, bndptr, higain);
+
+      edegrees = rinfo[higain].edegrees;
+      edegrees[0] = edegrees[1] = 0;
+      for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+        k = adjncy[j];
+        if (where[k] == 2) 
+          rinfo[k].edegrees[to] -= vwgt[higain];
+        else
+          edegrees[where[k]] += vwgt[k];
+      }
+
+      /* Push nodes out of the separator */
+      for (j=mptr[nswaps]; j<mptr[nswaps+1]; j++) {
+        k = mind[j];
+        ASSERT(where[k] == 2);
+        where[k] = other;
+        INC_DEC(pwgts[other], pwgts[2], vwgt[k]);
+        BNDDelete(nbnd, bndind, bndptr, k);
+        for (jj=xadj[k]; jj<xadj[k+1]; jj++) {
+          kk = adjncy[jj];
+          if (where[kk] == 2) 
+            rinfo[kk].edegrees[other] += vwgt[k];
+        }
+      }
+    }
+
+    ASSERT(mincut == pwgts[2]);
+
+    IFSET(ctrl->dbglvl, DBG_REFINE,
+      printf("\tMinimum sep: %6d at %5d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, mincutorder, pwgts[0], pwgts[1], nbnd));
+
+    graph->mincut = mincut;
+    graph->nbnd = nbnd;
+
+    if (mincutorder == -1 || mincut >= initcut)
+      break;
+  }
+
+  PQueueFree(ctrl, &parts[0]);
+  PQueueFree(ctrl, &parts[1]);
+
+  idxwspacefree(ctrl, nvtxs+1);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+/*************************************************************************
+* This function performs a node-based FM refinement. This is the 
+* one-way version 
+**************************************************************************/
+void FM_2WayNodeRefine_OneSided(CtrlType *ctrl, GraphType *graph, float ubfactor, int npasses)
+{
+  int i, ii, j, k, jj, kk, nvtxs, nbnd, nswaps, nmind;
+  idxtype *xadj, *vwgt, *adjncy, *where, *pwgts, *edegrees, *bndind, *bndptr;
+  idxtype *mptr, *mind, *swaps, *perm;
+  PQueueType parts; 
+  NRInfoType *rinfo;
+  int higain, oldgain, mincut, initcut, mincutorder;	
+  int pass, to, other, limit;
+  int badmaxpwgt, mindiff, newdiff;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  vwgt = graph->vwgt;
+
+  bndind = graph->bndind;
+  bndptr = graph->bndptr;
+  where = graph->where;
+  pwgts = graph->pwgts;
+  rinfo = graph->nrinfo;
+
+  PQueueInit(ctrl, &parts, nvtxs, ComputeMaxNodeGain(nvtxs, xadj, adjncy, vwgt));
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  swaps = idxwspacemalloc(ctrl, nvtxs);
+  mptr = idxwspacemalloc(ctrl, nvtxs);
+  mind = idxwspacemalloc(ctrl, nvtxs+1);
+
+  IFSET(ctrl->dbglvl, DBG_REFINE,
+    printf("Partitions-N1: [%6d %6d] Nv-Nb[%6d %6d]. ISep: %6d\n", pwgts[0], pwgts[1], graph->nvtxs, graph->nbnd, graph->mincut));
+
+  badmaxpwgt = (int)(ubfactor*(pwgts[0]+pwgts[1]+pwgts[2])/2);
+
+  to = (pwgts[0] < pwgts[1] ? 1 : 0);
+  for (pass=0; pass<npasses; pass++) {
+    other = to; 
+    to = (to+1)%2;
+
+    PQueueReset(&parts);
+
+    mincutorder = -1;
+    initcut = mincut = graph->mincut;
+    nbnd = graph->nbnd;
+
+    RandomPermute(nbnd, perm, 1);
+    for (ii=0; ii<nbnd; ii++) {
+      i = bndind[perm[ii]];
+      ASSERT(where[i] == 2);
+      PQueueInsert(&parts, i, vwgt[i]-rinfo[i].edegrees[other]);
+    }
+
+    ASSERT(CheckNodeBnd(graph, nbnd));
+    ASSERT(CheckNodePartitionParams(graph));
+
+    limit = (ctrl->oflags&OFLAG_COMPRESS ? amin(5*nbnd, 400) : amin(2*nbnd, 300));
+
+    /******************************************************
+    * Get into the FM loop
+    *******************************************************/
+    mptr[0] = nmind = 0;
+    mindiff = abs(pwgts[0]-pwgts[1]);
+    for (nswaps=0; nswaps<nvtxs; nswaps++) {
+
+      if ((higain = PQueueGetMax(&parts)) == -1)
+        break;
+
+      ASSERT(bndptr[higain] != -1);
+
+      if (pwgts[to]+vwgt[higain] > badmaxpwgt)
+        break;  /* No point going any further. Balance will be bad */
+
+      pwgts[2] -= (vwgt[higain]-rinfo[higain].edegrees[other]);
+
+      newdiff = abs(pwgts[to]+vwgt[higain] - (pwgts[other]-rinfo[higain].edegrees[other]));
+      if (pwgts[2] < mincut || (pwgts[2] == mincut && newdiff < mindiff)) {
+        mincut = pwgts[2];
+        mincutorder = nswaps;
+        mindiff = newdiff;
+      }
+      else {
+        if (nswaps - mincutorder > limit) {
+          pwgts[2] += (vwgt[higain]-rinfo[higain].edegrees[other]);
+          break; /* No further improvement, break out */
+        }
+      }
+
+      BNDDelete(nbnd, bndind, bndptr, higain);
+      pwgts[to] += vwgt[higain];
+      where[higain] = to;
+      swaps[nswaps] = higain;  
+
+
+      /**********************************************************
+      * Update the degrees of the affected nodes
+      ***********************************************************/
+      for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+        k = adjncy[j];
+        if (where[k] == 2) { /* For the in-separator vertices modify their edegree[to] */
+          rinfo[k].edegrees[to] += vwgt[higain];
+        }
+        else if (where[k] == other) { /* This vertex is pulled into the separator */
+          ASSERTP(bndptr[k] == -1, ("%d %d %d\n", k, bndptr[k], where[k]));
+          BNDInsert(nbnd, bndind, bndptr, k);
+
+          mind[nmind++] = k;  /* Keep track for rollback */
+          where[k] = 2;
+          pwgts[other] -= vwgt[k];
+
+          edegrees = rinfo[k].edegrees;
+          edegrees[0] = edegrees[1] = 0;
+          for (jj=xadj[k]; jj<xadj[k+1]; jj++) {
+            kk = adjncy[jj];
+            if (where[kk] != 2) 
+              edegrees[where[kk]] += vwgt[kk];
+            else {
+              oldgain = vwgt[kk]-rinfo[kk].edegrees[other];
+              rinfo[kk].edegrees[other] -= vwgt[k];
+
+              /* Since the moves are one-sided this vertex has not been moved yet */
+              PQueueUpdateUp(&parts, kk, oldgain, oldgain+vwgt[k]); 
+            }
+          }
+
+          /* Insert the new vertex into the priority queue. Safe due to one-sided moves */
+          PQueueInsert(&parts, k, vwgt[k]-edegrees[other]);
+        }
+      }
+      mptr[nswaps+1] = nmind;
+
+
+      IFSET(ctrl->dbglvl, DBG_MOVEINFO,
+            printf("Moved %6d to %3d, Gain: %5d [%5d] \t[%5d %5d %5d] [%3d %2d]\n", 
+                       higain, to, (vwgt[higain]-rinfo[higain].edegrees[other]), vwgt[higain], pwgts[0], pwgts[1], pwgts[2], nswaps, limit));
+
+    }
+
+
+    /****************************************************************
+    * Roll back computation 
+    *****************************************************************/
+    for (nswaps--; nswaps>mincutorder; nswaps--) {
+      higain = swaps[nswaps];
+
+      ASSERT(CheckNodePartitionParams(graph));
+      ASSERT(where[higain] == to);
+
+      INC_DEC(pwgts[2], pwgts[to], vwgt[higain]);
+      where[higain] = 2;
+      BNDInsert(nbnd, bndind, bndptr, higain);
+
+      edegrees = rinfo[higain].edegrees;
+      edegrees[0] = edegrees[1] = 0;
+      for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+        k = adjncy[j];
+        if (where[k] == 2) 
+          rinfo[k].edegrees[to] -= vwgt[higain];
+        else
+          edegrees[where[k]] += vwgt[k];
+      }
+
+      /* Push nodes out of the separator */
+      for (j=mptr[nswaps]; j<mptr[nswaps+1]; j++) {
+        k = mind[j];
+        ASSERT(where[k] == 2);
+        where[k] = other;
+        INC_DEC(pwgts[other], pwgts[2], vwgt[k]);
+        BNDDelete(nbnd, bndind, bndptr, k);
+        for (jj=xadj[k]; jj<xadj[k+1]; jj++) {
+          kk = adjncy[jj];
+          if (where[kk] == 2) 
+            rinfo[kk].edegrees[other] += vwgt[k];
+        }
+      }
+    }
+
+    ASSERT(mincut == pwgts[2]);
+
+    IFSET(ctrl->dbglvl, DBG_REFINE,
+      printf("\tMinimum sep: %6d at %5d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, mincutorder, pwgts[0], pwgts[1], nbnd));
+
+    graph->mincut = mincut;
+    graph->nbnd = nbnd;
+
+    if (pass%2 == 1 && (mincutorder == -1 || mincut >= initcut))
+      break;
+  }
+
+  PQueueFree(ctrl, &parts);
+
+  idxwspacefree(ctrl, nvtxs+1);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+
+/*************************************************************************
+* This function performs a node-based FM refinement 
+**************************************************************************/
+void FM_2WayNodeBalance(CtrlType *ctrl, GraphType *graph, float ubfactor)
+{
+  int i, ii, j, k, jj, kk, nvtxs, nbnd, nswaps;
+  idxtype *xadj, *vwgt, *adjncy, *where, *pwgts, *edegrees, *bndind, *bndptr;
+  idxtype *perm, *moved;
+  PQueueType parts; 
+  NRInfoType *rinfo;
+  int higain, oldgain;	
+  int pass, to, other;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  vwgt = graph->vwgt;
+
+  bndind = graph->bndind;
+  bndptr = graph->bndptr;
+  where = graph->where;
+  pwgts = graph->pwgts;
+  rinfo = graph->nrinfo;
+
+  if (abs(pwgts[0]-pwgts[1]) < (int)((ubfactor-1.0)*(pwgts[0]+pwgts[1])))
+    return;
+  if (abs(pwgts[0]-pwgts[1]) < 3*idxsum(nvtxs, vwgt)/nvtxs)
+    return;
+
+  to = (pwgts[0] < pwgts[1] ? 0 : 1); 
+  other = (to+1)%2;
+
+  PQueueInit(ctrl, &parts, nvtxs, ComputeMaxNodeGain(nvtxs, xadj, adjncy, vwgt));
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  moved = idxset(nvtxs, -1, idxwspacemalloc(ctrl, nvtxs));
+
+  IFSET(ctrl->dbglvl, DBG_REFINE,
+    printf("Partitions: [%6d %6d] Nv-Nb[%6d %6d]. ISep: %6d [B]\n", pwgts[0], pwgts[1], graph->nvtxs, graph->nbnd, graph->mincut));
+
+  nbnd = graph->nbnd;
+  RandomPermute(nbnd, perm, 1);
+  for (ii=0; ii<nbnd; ii++) {
+    i = bndind[perm[ii]];
+    ASSERT(where[i] == 2);
+    PQueueInsert(&parts, i, vwgt[i]-rinfo[i].edegrees[other]);
+  }
+
+  ASSERT(CheckNodeBnd(graph, nbnd));
+  ASSERT(CheckNodePartitionParams(graph));
+
+  /******************************************************
+  * Get into the FM loop
+  *******************************************************/
+  for (nswaps=0; nswaps<nvtxs; nswaps++) {
+    if ((higain = PQueueGetMax(&parts)) == -1)
+      break;
+
+    moved[higain] = 1;
+
+    if (pwgts[other] - rinfo[higain].edegrees[other] < (pwgts[0]+pwgts[1])/2) 
+      continue;
+#ifdef XXX
+    if (pwgts[other] - rinfo[higain].edegrees[other] < pwgts[to]+vwgt[higain]) 
+      break;
+#endif
+
+    ASSERT(bndptr[higain] != -1);
+
+    pwgts[2] -= (vwgt[higain]-rinfo[higain].edegrees[other]);
+
+    BNDDelete(nbnd, bndind, bndptr, higain);
+    pwgts[to] += vwgt[higain];
+    where[higain] = to;
+
+    IFSET(ctrl->dbglvl, DBG_MOVEINFO,
+          printf("Moved %6d to %3d, Gain: %3d, \t[%5d %5d %5d]\n", higain, to, vwgt[higain]-rinfo[higain].edegrees[other], pwgts[0], pwgts[1], pwgts[2]));
+
+
+    /**********************************************************
+    * Update the degrees of the affected nodes
+    ***********************************************************/
+    for (j=xadj[higain]; j<xadj[higain+1]; j++) {
+      k = adjncy[j];
+      if (where[k] == 2) { /* For the in-separator vertices modify their edegree[to] */
+        rinfo[k].edegrees[to] += vwgt[higain];
+      }
+      else if (where[k] == other) { /* This vertex is pulled into the separator */
+        ASSERTP(bndptr[k] == -1, ("%d %d %d\n", k, bndptr[k], where[k]));
+        BNDInsert(nbnd, bndind, bndptr, k);
+
+        where[k] = 2;
+        pwgts[other] -= vwgt[k];
+
+        edegrees = rinfo[k].edegrees;
+        edegrees[0] = edegrees[1] = 0;
+        for (jj=xadj[k]; jj<xadj[k+1]; jj++) {
+          kk = adjncy[jj];
+          if (where[kk] != 2) 
+            edegrees[where[kk]] += vwgt[kk];
+          else {
+            ASSERT(bndptr[kk] != -1);
+            oldgain = vwgt[kk]-rinfo[kk].edegrees[other];
+            rinfo[kk].edegrees[other] -= vwgt[k];
+
+            if (moved[kk] == -1)
+              PQueueUpdateUp(&parts, kk, oldgain, oldgain+vwgt[k]);
+          }
+        }
+
+        /* Insert the new vertex into the priority queue */
+        PQueueInsert(&parts, k, vwgt[k]-edegrees[other]);
+      }
+    }
+
+    if (pwgts[to] > pwgts[other])
+      break;
+  }
+
+  IFSET(ctrl->dbglvl, DBG_REFINE,
+    printf("\tBalanced sep: %6d at %4d, PWGTS: [%6d %6d], NBND: %6d\n", pwgts[2], nswaps, pwgts[0], pwgts[1], nbnd));
+
+  graph->mincut = pwgts[2];
+  graph->nbnd = nbnd;
+
+
+  PQueueFree(ctrl, &parts);
+
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+/*************************************************************************
+* This function computes the maximum possible gain for a vertex
+**************************************************************************/
+int ComputeMaxNodeGain(int nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt)
+{
+  int i, j, k, max;
+
+  max = 0;
+  for (j=xadj[0]; j<xadj[1]; j++)
+    max += vwgt[adjncy[j]];
+
+  for (i=1; i<nvtxs; i++) {
+    for (k=0, j=xadj[i]; j<xadj[i+1]; j++)
+      k += vwgt[adjncy[j]];
+    if (max < k)
+      max = k;
+  }
+
+  return max;
+}
+   
+
diff --git a/Metis/srefine.c b/Metis/srefine.c
new file mode 100644
index 0000000000..a0cf88d101
--- /dev/null
+++ b/Metis/srefine.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * srefine.c
+ *
+ * This file contains code for the separator refinement algortihms
+ *
+ * Started 8/1/97
+ * George
+ *
+ * $Id: srefine.c,v 1.1 2005-09-07 14:36:46 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function is the entry point of the separator refinement
+**************************************************************************/
+void Refine2WayNode(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, float ubfactor)
+{
+
+  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr));
+
+  for (;;) {
+    IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr));
+    if (ctrl->RType != 15)
+      FM_2WayNodeBalance(ctrl, graph, ubfactor); 
+
+    switch (ctrl->RType) {
+      case 1:
+        FM_2WayNodeRefine(ctrl, graph, ubfactor, 8); 
+        break;
+      case 2:
+        FM_2WayNodeRefine_OneSided(ctrl, graph, ubfactor, 8); 
+        break;
+      case 3:
+        FM_2WayNodeRefine(ctrl, graph, ubfactor, 8); 
+        FM_2WayNodeRefine_OneSided(ctrl, graph, ubfactor, 8); 
+        break;
+      case 4:
+        FM_2WayNodeRefine_OneSided(ctrl, graph, ubfactor, 8); 
+        FM_2WayNodeRefine(ctrl, graph, ubfactor, 8); 
+        break;
+      case 5:
+        FM_2WayNodeRefineEqWgt(ctrl, graph, 8); 
+        break;
+    }
+    IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr));
+
+    if (graph == orggraph) 
+      break;
+
+    graph = graph->finer;
+    IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr));
+    Project2WayNodePartition(ctrl, graph);
+    IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr));
+  }
+
+  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr));
+}
+
+
+/*************************************************************************
+* This function allocates memory for 2-way edge refinement
+**************************************************************************/
+void Allocate2WayNodePartitionMemory(CtrlType *ctrl, GraphType *graph)
+{
+  int nvtxs, pad64;
+
+  nvtxs = graph->nvtxs;
+
+  pad64 = (3*nvtxs+3)%2;
+
+  graph->rdata = idxmalloc(3*nvtxs+3+(sizeof(NRInfoType)/sizeof(idxtype))*nvtxs+pad64, "Allocate2WayPartitionMemory: rdata");
+  graph->pwgts          = graph->rdata;
+  graph->where          = graph->rdata + 3;
+  graph->bndptr         = graph->rdata + nvtxs + 3;
+  graph->bndind         = graph->rdata + 2*nvtxs + 3;
+  graph->nrinfo         = (NRInfoType *)(graph->rdata + 3*nvtxs + 3 + pad64);
+}
+
+
+
+/*************************************************************************
+* This function computes the initial id/ed 
+**************************************************************************/
+void Compute2WayNodePartitionParams(CtrlType *ctrl, GraphType *graph)
+{
+  int i, j, k, l, nvtxs, nbnd;
+  idxtype *xadj, *adjncy, *adjwgt, *vwgt;
+  idxtype *where, *pwgts, *bndind, *bndptr, *edegrees;
+  NRInfoType *rinfo;
+  int me, other;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  vwgt = graph->vwgt;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  where = graph->where;
+  rinfo = graph->nrinfo;
+  pwgts = idxset(3, 0, graph->pwgts);
+  bndind = graph->bndind;
+  bndptr = idxset(nvtxs, -1, graph->bndptr);
+
+
+  /*------------------------------------------------------------
+  / Compute now the separator external degrees
+  /------------------------------------------------------------*/
+  nbnd = 0;
+  for (i=0; i<nvtxs; i++) {
+    me = where[i];
+    pwgts[me] += vwgt[i];
+
+    ASSERT(me >=0 && me <= 2);
+
+    if (me == 2) { /* If it is on the separator do some computations */
+      BNDInsert(nbnd, bndind, bndptr, i);
+
+      edegrees = rinfo[i].edegrees;
+      edegrees[0] = edegrees[1] = 0;
+
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        other = where[adjncy[j]];
+        if (other != 2)
+          edegrees[other] += vwgt[adjncy[j]];
+      }
+    }
+  }
+
+  ASSERT(CheckNodeBnd(graph, nbnd));
+
+  graph->mincut = pwgts[2];
+  graph->nbnd = nbnd;
+}
+
+
+/*************************************************************************
+* This function computes the initial id/ed 
+**************************************************************************/
+void Project2WayNodePartition(CtrlType *ctrl, GraphType *graph)
+{
+  int i, j, nvtxs;
+  idxtype *cmap, *where, *cwhere;
+  GraphType *cgraph;
+
+  cgraph = graph->coarser;
+  cwhere = cgraph->where;
+
+  nvtxs = graph->nvtxs;
+  cmap = graph->cmap;
+
+  Allocate2WayNodePartitionMemory(ctrl, graph);
+  where = graph->where;
+  
+  /* Project the partition */
+  for (i=0; i<nvtxs; i++) {
+    where[i] = cwhere[cmap[i]];
+    ASSERTP(where[i] >= 0 && where[i] <= 2, ("%d %d %d %d\n", i, cmap[i], where[i], cwhere[cmap[i]]));
+  }
+
+  FreeGraph(graph->coarser);
+  graph->coarser = NULL;
+
+  Compute2WayNodePartitionParams(ctrl, graph);
+}
diff --git a/Metis/stat.c b/Metis/stat.c
new file mode 100644
index 0000000000..74d22e9989
--- /dev/null
+++ b/Metis/stat.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * stat.c
+ *
+ * This file computes various statistics
+ *
+ * Started 7/25/97
+ * George
+ *
+ * $Id: stat.c,v 1.1 2005-09-07 14:36:46 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function computes cuts and balance information
+**************************************************************************/
+void ComputePartitionInfo(GraphType *graph, int nparts, idxtype *where)
+{
+  int i, j, k, nvtxs, ncon, mustfree=0;
+  idxtype *xadj, *adjncy, *vwgt, *adjwgt, *kpwgts, *tmpptr;
+  idxtype *padjncy, *padjwgt, *padjcut;
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  vwgt = graph->vwgt;
+  adjwgt = graph->adjwgt;
+
+  if (vwgt == NULL) {
+    vwgt = graph->vwgt = idxsmalloc(nvtxs, 1, "vwgt");
+    mustfree = 1;
+  }
+  if (adjwgt == NULL) {
+    adjwgt = graph->adjwgt = idxsmalloc(xadj[nvtxs], 1, "adjwgt");
+    mustfree += 2;
+  }
+
+  printf("%d-way Cut: %5d, Vol: %5d, ", nparts, ComputeCut(graph, where), ComputeVolume(graph, where));
+
+  /* Compute balance information */
+  kpwgts = idxsmalloc(ncon*nparts, 0, "ComputePartitionInfo: kpwgts");
+
+  for (i=0; i<nvtxs; i++) {
+    for (j=0; j<ncon; j++) 
+      kpwgts[where[i]*ncon+j] += vwgt[i*ncon+j];
+  }
+
+  if (ncon == 1) {
+    printf("\tBalance: %5.3f out of %5.3f\n", 
+            1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts)),
+            1.0*nparts*vwgt[idxamax(nvtxs, vwgt)]/(1.0*idxsum(nparts, kpwgts)));
+  }
+  else {
+    printf("\tBalance:");
+    for (j=0; j<ncon; j++) 
+      printf(" (%5.3f out of %5.3f)", 
+            1.0*nparts*kpwgts[ncon*idxamax_strd(nparts, kpwgts+j, ncon)+j]/(1.0*idxsum_strd(nparts, kpwgts+j, ncon)),
+            1.0*nparts*vwgt[ncon*idxamax_strd(nvtxs, vwgt+j, ncon)+j]/(1.0*idxsum_strd(nparts, kpwgts+j, ncon)));
+    printf("\n");
+  }
+
+
+  /* Compute p-adjncy information */
+  padjncy = idxsmalloc(nparts*nparts, 0, "ComputePartitionInfo: padjncy");
+  padjwgt = idxsmalloc(nparts*nparts, 0, "ComputePartitionInfo: padjwgt");
+  padjcut = idxsmalloc(nparts*nparts, 0, "ComputePartitionInfo: padjwgt");
+
+  idxset(nparts, 0, kpwgts);
+  for (i=0; i<nvtxs; i++) {
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      if (where[i] != where[adjncy[j]]) {
+        padjncy[where[i]*nparts+where[adjncy[j]]] = 1;
+        padjcut[where[i]*nparts+where[adjncy[j]]] += adjwgt[j];
+        if (kpwgts[where[adjncy[j]]] == 0) {
+          padjwgt[where[i]*nparts+where[adjncy[j]]]++;
+          kpwgts[where[adjncy[j]]] = 1;
+        }
+      }
+    }
+    for (j=xadj[i]; j<xadj[i+1]; j++) 
+      kpwgts[where[adjncy[j]]] = 0;
+  }
+
+  for (i=0; i<nparts; i++)
+    kpwgts[i] = idxsum(nparts, padjncy+i*nparts);
+  printf("Min/Max/Avg/Bal # of adjacent     subdomains: %5d %5d %5.2f %7.3f\n",
+    kpwgts[idxamin(nparts, kpwgts)], kpwgts[idxamax(nparts, kpwgts)], 
+    1.0*idxsum(nparts, kpwgts)/(1.0*nparts), 
+    1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts)));
+
+  for (i=0; i<nparts; i++)
+    kpwgts[i] = idxsum(nparts, padjcut+i*nparts);
+  printf("Min/Max/Avg/Bal # of adjacent subdomain cuts: %5d %5d %5d %7.3f\n",
+    kpwgts[idxamin(nparts, kpwgts)], kpwgts[idxamax(nparts, kpwgts)], idxsum(nparts, kpwgts)/nparts, 
+    1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts)));
+
+  for (i=0; i<nparts; i++)
+    kpwgts[i] = idxsum(nparts, padjwgt+i*nparts);
+  printf("Min/Max/Avg/Bal/Frac # of interface    nodes: %5d %5d %5d %7.3f %7.3f\n",
+    kpwgts[idxamin(nparts, kpwgts)], kpwgts[idxamax(nparts, kpwgts)], idxsum(nparts, kpwgts)/nparts, 
+    1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts)), 1.0*idxsum(nparts, kpwgts)/(1.0*nvtxs));
+
+  tmpptr = graph->where;
+  graph->where = where;
+  for (i=0; i<nparts; i++)
+    IsConnectedSubdomain(NULL, graph, i, 1);
+  graph->where = tmpptr;
+
+  if (mustfree == 1 || mustfree == 3) {
+    free(vwgt);
+    graph->vwgt = NULL;
+  }
+  if (mustfree == 2 || mustfree == 3) {
+    free(adjwgt);
+    graph->adjwgt = NULL;
+  }
+
+  GKfree(&kpwgts, &padjncy, &padjwgt, &padjcut, LTERM);
+}
+
+
+/*************************************************************************
+* This function computes cuts and balance information
+**************************************************************************/
+void ComputePartitionInfoBipartite(GraphType *graph, int nparts, idxtype *where)
+{
+  int i, j, k, nvtxs, ncon, mustfree=0;
+  idxtype *xadj, *adjncy, *vwgt, *vsize, *adjwgt, *kpwgts, *tmpptr;
+  idxtype *padjncy, *padjwgt, *padjcut;
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  vwgt = graph->vwgt;
+  vsize = graph->vsize;
+  adjwgt = graph->adjwgt;
+
+  if (vwgt == NULL) {
+    vwgt = graph->vwgt = idxsmalloc(nvtxs, 1, "vwgt");
+    mustfree = 1;
+  }
+  if (adjwgt == NULL) {
+    adjwgt = graph->adjwgt = idxsmalloc(xadj[nvtxs], 1, "adjwgt");
+    mustfree += 2;
+  }
+
+  printf("%d-way Cut: %5d, Vol: %5d, ", nparts, ComputeCut(graph, where), ComputeVolume(graph, where));
+
+  /* Compute balance information */
+  kpwgts = idxsmalloc(ncon*nparts, 0, "ComputePartitionInfo: kpwgts");
+
+  for (i=0; i<nvtxs; i++) {
+    for (j=0; j<ncon; j++) 
+      kpwgts[where[i]*ncon+j] += vwgt[i*ncon+j];
+  }
+
+  if (ncon == 1) {
+    printf("\tBalance: %5.3f out of %5.3f\n", 
+            1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts)),
+            1.0*nparts*vwgt[idxamax(nvtxs, vwgt)]/(1.0*idxsum(nparts, kpwgts)));
+  }
+  else {
+    printf("\tBalance:");
+    for (j=0; j<ncon; j++) 
+      printf(" (%5.3f out of %5.3f)", 
+            1.0*nparts*kpwgts[ncon*idxamax_strd(nparts, kpwgts+j, ncon)+j]/(1.0*idxsum_strd(nparts, kpwgts+j, ncon)),
+            1.0*nparts*vwgt[ncon*idxamax_strd(nvtxs, vwgt+j, ncon)+j]/(1.0*idxsum_strd(nparts, kpwgts+j, ncon)));
+    printf("\n");
+  }
+
+
+  /* Compute p-adjncy information */
+  padjncy = idxsmalloc(nparts*nparts, 0, "ComputePartitionInfo: padjncy");
+  padjwgt = idxsmalloc(nparts*nparts, 0, "ComputePartitionInfo: padjwgt");
+  padjcut = idxsmalloc(nparts*nparts, 0, "ComputePartitionInfo: padjwgt");
+
+  idxset(nparts, 0, kpwgts);
+  for (i=0; i<nvtxs; i++) {
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      if (where[i] != where[adjncy[j]]) {
+        padjncy[where[i]*nparts+where[adjncy[j]]] = 1;
+        padjcut[where[i]*nparts+where[adjncy[j]]] += adjwgt[j];
+        if (kpwgts[where[adjncy[j]]] == 0) {
+          padjwgt[where[i]*nparts+where[adjncy[j]]] += vsize[i];
+          kpwgts[where[adjncy[j]]] = 1;
+        }
+      }
+    }
+    for (j=xadj[i]; j<xadj[i+1]; j++) 
+      kpwgts[where[adjncy[j]]] = 0;
+  }
+
+  for (i=0; i<nparts; i++)
+    kpwgts[i] = idxsum(nparts, padjncy+i*nparts);
+  printf("Min/Max/Avg/Bal # of adjacent     subdomains: %5d %5d %5d %7.3f\n",
+    kpwgts[idxamin(nparts, kpwgts)], kpwgts[idxamax(nparts, kpwgts)], idxsum(nparts, kpwgts)/nparts, 
+    1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts)));
+
+  for (i=0; i<nparts; i++)
+    kpwgts[i] = idxsum(nparts, padjcut+i*nparts);
+  printf("Min/Max/Avg/Bal # of adjacent subdomain cuts: %5d %5d %5d %7.3f\n",
+    kpwgts[idxamin(nparts, kpwgts)], kpwgts[idxamax(nparts, kpwgts)], idxsum(nparts, kpwgts)/nparts, 
+    1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts)));
+
+  for (i=0; i<nparts; i++)
+    kpwgts[i] = idxsum(nparts, padjwgt+i*nparts);
+  printf("Min/Max/Avg/Bal/Frac # of interface    nodes: %5d %5d %5d %7.3f %7.3f\n",
+    kpwgts[idxamin(nparts, kpwgts)], kpwgts[idxamax(nparts, kpwgts)], idxsum(nparts, kpwgts)/nparts, 
+    1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts)), 1.0*idxsum(nparts, kpwgts)/(1.0*nvtxs));
+
+
+  if (mustfree == 1 || mustfree == 3) {
+    free(vwgt);
+    graph->vwgt = NULL;
+  }
+  if (mustfree == 2 || mustfree == 3) {
+    free(adjwgt);
+    graph->adjwgt = NULL;
+  }
+
+  GKfree(&kpwgts, &padjncy, &padjwgt, &padjcut, LTERM);
+}
+
+
+
+/*************************************************************************
+* This function computes the balance of the partitioning
+**************************************************************************/
+void ComputePartitionBalance(GraphType *graph, int nparts, idxtype *where, float *ubvec)
+{
+  int i, j, nvtxs, ncon;
+  idxtype *kpwgts, *vwgt;
+  float balance;
+
+  nvtxs = graph->nvtxs;
+  ncon = graph->ncon;
+  vwgt = graph->vwgt;
+
+  kpwgts = idxsmalloc(nparts, 0, "ComputePartitionInfo: kpwgts");
+
+  if (vwgt == NULL) {
+    for (i=0; i<nvtxs; i++)
+      kpwgts[where[i]]++;
+    ubvec[0] = 1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*nvtxs);
+  }
+  else {
+    for (j=0; j<ncon; j++) {
+      idxset(nparts, 0, kpwgts);
+      for (i=0; i<graph->nvtxs; i++)
+        kpwgts[where[i]] += vwgt[i*ncon+j];
+
+      ubvec[j] = 1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts));
+    }
+  }
+
+  free(kpwgts);
+
+}
+
+
+/*************************************************************************
+* This function computes the balance of the element partitioning
+**************************************************************************/
+float ComputeElementBalance(int ne, int nparts, idxtype *where)
+{
+  int i;
+  idxtype *kpwgts;
+  float balance;
+
+  kpwgts = idxsmalloc(nparts, 0, "ComputeElementBalance: kpwgts");
+
+  for (i=0; i<ne; i++)
+    kpwgts[where[i]]++;
+
+  balance = 1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts));
+
+  free(kpwgts);
+
+  return balance;
+
+}
diff --git a/Metis/struct.h b/Metis/struct.h
new file mode 100644
index 0000000000..e5ba553e9a
--- /dev/null
+++ b/Metis/struct.h
@@ -0,0 +1,251 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * struct.h
+ *
+ * This file contains data structures for ILU routines.
+ *
+ * Started 9/26/95
+ * George
+ *
+ * $Id: struct.h,v 1.1 2005-09-07 14:36:46 remacle Exp $
+ */
+
+/* Undefine the following #define in order to use short int as the idxtype */
+#define IDXTYPE_INT
+
+/* Indexes are as long as integers for now */
+#ifdef IDXTYPE_INT
+typedef int idxtype;
+#else
+typedef short idxtype;
+#endif
+
+#define MAXIDX	(1<<8*sizeof(idxtype)-2)
+
+
+/*************************************************************************
+* The following data structure stores key-value pair
+**************************************************************************/
+struct KeyValueType {
+  idxtype key;
+  idxtype val;
+};
+
+typedef struct KeyValueType KeyValueType;
+
+
+/*************************************************************************
+* The following data structure will hold a node of a doubly-linked list.
+**************************************************************************/
+struct ListNodeType {
+  int id;                       	/* The id value of the node */
+  struct ListNodeType *prev, *next;     /* It's a doubly-linked list */
+};
+
+typedef struct ListNodeType ListNodeType;
+
+
+
+/*************************************************************************
+* The following data structure is used to store the buckets for the 
+* refinment algorithms
+**************************************************************************/
+struct PQueueType {
+  int type;                     /* The type of the representation used */
+  int nnodes;
+  int maxnodes;
+  int mustfree;
+
+  /* Linear array version of the data structures */
+  int pgainspan, ngainspan;     /* plus and negative gain span */
+  int maxgain;
+  ListNodeType *nodes;
+  ListNodeType **buckets;
+
+  /* Heap version of the data structure */
+  KeyValueType *heap;
+  idxtype *locator;
+};
+
+typedef struct PQueueType PQueueType;
+
+
+/*************************************************************************
+* The following data structure stores an edge
+**************************************************************************/
+struct edegreedef {
+  idxtype pid;
+  idxtype ed;
+};
+typedef struct edegreedef EDegreeType;
+
+
+/*************************************************************************
+* The following data structure stores an edge for vol
+**************************************************************************/
+struct vedegreedef {
+  idxtype pid;
+  idxtype ed, ned;
+  idxtype gv;
+};
+typedef struct vedegreedef VEDegreeType;
+
+
+/*************************************************************************
+* This data structure holds various working space data
+**************************************************************************/
+struct workspacedef {
+  idxtype *core;			/* Where pairs, indices, and degrees are coming from */
+  int maxcore, ccore;
+
+  EDegreeType *edegrees;
+  VEDegreeType *vedegrees;
+  int cdegree;
+
+  idxtype *auxcore;			/* This points to the memory of the edegrees */
+
+  idxtype *pmat;			/* An array of k^2 used for eliminating domain 
+                                           connectivity in k-way refinement */
+};
+
+typedef struct workspacedef WorkSpaceType;
+
+
+/*************************************************************************
+* The following data structure holds information on degrees for k-way
+* partition
+**************************************************************************/
+struct rinfodef {
+ int id, ed;            	/* ID/ED of nodes */
+ int ndegrees;          	/* The number of different ext-degrees */
+ EDegreeType *edegrees;     	/* List of edges */
+};
+
+typedef struct rinfodef RInfoType;
+
+
+/*************************************************************************
+* The following data structure holds information on degrees for k-way
+* vol-based partition
+**************************************************************************/
+struct vrinfodef {
+ int id, ed, nid;            	/* ID/ED of nodes */
+ int gv;            		/* IV/EV of nodes */
+ int ndegrees;          	/* The number of different ext-degrees */
+ VEDegreeType *edegrees;     	/* List of edges */
+};
+
+typedef struct vrinfodef VRInfoType;
+
+
+/*************************************************************************
+* The following data structure holds information on degrees for k-way
+* partition
+**************************************************************************/
+struct nrinfodef {
+ idxtype edegrees[2];  
+};
+
+typedef struct nrinfodef NRInfoType;
+
+
+/*************************************************************************
+* This data structure holds the input graph
+**************************************************************************/
+struct graphdef {
+  idxtype *gdata, *rdata;	/* Memory pools for graph and refinement data.
+                                   This is where memory is allocated and used
+                                   the rest of the fields in this structure */
+
+  int nvtxs, nedges;		/* The # of vertices and edges in the graph */
+  idxtype *xadj;		/* Pointers to the locally stored vertices */
+  idxtype *vwgt;		/* Vertex weights */
+  idxtype *vsize;		/* Vertex sizes for min-volume formulation */
+  idxtype *adjncy;		/* Array that stores the adjacency lists of nvtxs */
+  idxtype *adjwgt;		/* Array that stores the weights of the adjacency lists */
+
+  idxtype *adjwgtsum;		/* The sum of the adjacency weight of each vertex */
+
+  idxtype *label;
+
+  idxtype *cmap;
+
+  /* Partition parameters */
+  int mincut, minvol;
+  idxtype *where, *pwgts;
+  int nbnd;
+  idxtype *bndptr, *bndind;
+
+  /* Bisection refinement parameters */
+  idxtype *id, *ed;
+
+  /* K-way refinement parameters */
+  RInfoType *rinfo;
+
+  /* K-way volume refinement parameters */
+  VRInfoType *vrinfo;
+
+  /* Node refinement information */
+  NRInfoType *nrinfo;
+
+
+  /* Additional info needed by the MOC routines */
+  int ncon;			/* The # of constrains */ 
+  float *nvwgt;			/* Normalized vertex weights */
+  float *npwgts;		/* The normalized partition weights */
+
+  struct graphdef *coarser, *finer;
+};
+
+typedef struct graphdef GraphType;
+
+
+
+/*************************************************************************
+* The following data type implements a timer
+**************************************************************************/
+typedef double timer;
+
+
+/*************************************************************************
+* The following structure stores information used by Metis
+**************************************************************************/
+struct controldef {
+  int CoarsenTo;		/* The # of vertices in the coarsest graph */
+  int dbglvl;			/* Controls the debuging output of the program */
+  int CType;			/* The type of coarsening */
+  int IType;			/* The type of initial partitioning */
+  int RType;			/* The type of refinement */
+  int maxvwgt;			/* The maximum allowed weight for a vertex */
+  float nmaxvwgt;		/* The maximum allowed weight for a vertex for each constrain */
+  int optype;			/* Type of operation */
+  int pfactor;			/* .1*prunning factor */
+  int nseps;			/* The number of separators to be found during multiple bisections */
+  int oflags;
+
+  WorkSpaceType wspace;		/* Work Space Informations */
+
+  /* Various Timers */
+  timer TotalTmr, InitPartTmr, MatchTmr, ContractTmr, CoarsenTmr, UncoarsenTmr, 
+        SepTmr, RefTmr, ProjectTmr, SplitTmr, AuxTmr1, AuxTmr2, AuxTmr3, AuxTmr4, AuxTmr5, AuxTmr6;
+
+};
+
+typedef struct controldef CtrlType;
+
+
+/*************************************************************************
+* The following data structure stores max-partition weight info for 
+* Vertical MOC k-way refinement
+**************************************************************************/
+struct vpwgtdef {
+  float max[2][MAXNCON];
+  int imax[2][MAXNCON];
+};
+
+typedef struct vpwgtdef VPInfoType;
+
+
+
+
diff --git a/Metis/subdomains.c b/Metis/subdomains.c
new file mode 100644
index 0000000000..ec6ef674da
--- /dev/null
+++ b/Metis/subdomains.c
@@ -0,0 +1,1295 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * subdomains.c
+ *
+ * This file contains functions that deal with prunning the number of
+ * adjacent subdomains in KMETIS
+ *
+ * Started 7/15/98
+ * George
+ *
+ * $Id: subdomains.c,v 1.1 2005-09-07 14:36:46 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function performs k-way refinement
+**************************************************************************/
+void Random_KWayEdgeRefineMConn(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses, int ffactor)
+{
+  int i, ii, iii, j, jj, k, l, pass, nvtxs, nmoves, nbnd, tvwgt, myndegrees; 
+  int from, me, to, oldcut, vwgt, gain;
+  int maxndoms, nadd;
+  idxtype *xadj, *adjncy, *adjwgt;
+  idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts;
+  idxtype *phtable, *pmat, *pmatptr, *ndoms;
+  EDegreeType *myedegrees;
+  RInfoType *myrinfo;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+
+  where = graph->where;
+  pwgts = graph->pwgts;
+
+  pmat = ctrl->wspace.pmat;
+  phtable = idxwspacemalloc(ctrl, nparts);
+  ndoms = idxwspacemalloc(ctrl, nparts);
+
+  ComputeSubDomainGraph(graph, nparts, pmat, ndoms);
+
+  /* Setup the weight intervals of the various subdomains */
+  minwgt =  idxwspacemalloc(ctrl, nparts);
+  maxwgt = idxwspacemalloc(ctrl, nparts);
+  itpwgts = idxwspacemalloc(ctrl, nparts);
+  tvwgt = idxsum(nparts, pwgts);
+  ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt));
+
+  for (i=0; i<nparts; i++) {
+    itpwgts[i] = tpwgts[i]*tvwgt;
+    maxwgt[i] = tpwgts[i]*tvwgt*ubfactor;
+    minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor);
+  }
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+
+  IFSET(ctrl->dbglvl, DBG_REFINE,
+     printf("Partitions: [%6d %6d]-[%6d %6d], Balance: %5.3f, Nv-Nb[%6d %6d]. Cut: %6d\n",
+             pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], 
+             1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd,
+             graph->mincut));
+
+  for (pass=0; pass<npasses; pass++) {
+    ASSERT(ComputeCut(graph, where) == graph->mincut);
+
+    maxndoms = ndoms[idxamax(nparts, ndoms)];
+
+    oldcut = graph->mincut;
+    nbnd = graph->nbnd;
+
+    RandomPermute(nbnd, perm, 1);
+    for (nmoves=iii=0; iii<graph->nbnd; iii++) {
+      ii = perm[iii];
+      if (ii >= nbnd)
+        continue;
+      i = bndind[ii];
+
+      myrinfo = graph->rinfo+i;
+
+      if (myrinfo->ed >= myrinfo->id) { /* Total ED is too high */
+        from = where[i];
+        vwgt = graph->vwgt[i];
+
+        if (myrinfo->id > 0 && pwgts[from]-vwgt < minwgt[from]) 
+          continue;   /* This cannot be moved! */
+
+        myedegrees = myrinfo->edegrees;
+        myndegrees = myrinfo->ndegrees;
+
+        /* Determine the valid domains */
+        for (j=0; j<myndegrees; j++) {
+          to = myedegrees[j].pid;
+          phtable[to] = 1;
+          pmatptr = pmat + to*nparts;
+          for (nadd=0, k=0; k<myndegrees; k++) {
+            if (k == j)
+              continue;
+
+            l = myedegrees[k].pid;
+            if (pmatptr[l] == 0) {
+              if (ndoms[l] > maxndoms-1) {
+                phtable[to] = 0;
+                nadd = maxndoms;
+                break;
+              }
+              nadd++;
+            }
+          }
+          if (ndoms[to]+nadd > maxndoms)
+            phtable[to] = 0;
+          if (nadd == 0)
+            phtable[to] = 2;
+        }
+
+        /* Find the first valid move */
+        j = myrinfo->id;
+        for (k=0; k<myndegrees; k++) {
+          to = myedegrees[k].pid;
+          if (!phtable[to])
+            continue;
+          gain = myedegrees[k].ed-j; /* j = myrinfo->id. Allow good nodes to move */ 
+          if (pwgts[to]+vwgt <= maxwgt[to]+ffactor*gain && gain >= 0)  
+            break;
+        }
+        if (k == myndegrees)
+          continue;  /* break out if you did not find a candidate */
+
+        for (j=k+1; j<myndegrees; j++) {
+          to = myedegrees[j].pid;
+          if (!phtable[to])
+            continue;
+          if ((myedegrees[j].ed > myedegrees[k].ed && pwgts[to]+vwgt <= maxwgt[to]) ||
+              (myedegrees[j].ed == myedegrees[k].ed && 
+               itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid]))
+            k = j;
+        }
+
+        to = myedegrees[k].pid;
+
+        j = 0;
+        if (myedegrees[k].ed-myrinfo->id > 0)
+          j = 1;
+        else if (myedegrees[k].ed-myrinfo->id == 0) {
+          if (/*(iii&7) == 0  ||*/ phtable[myedegrees[k].pid] == 2 || pwgts[from] >= maxwgt[from] || itpwgts[from]*(pwgts[to]+vwgt) < itpwgts[to]*pwgts[from])
+            j = 1;
+        }
+        if (j == 0)
+          continue;
+          
+        /*=====================================================================
+        * If we got here, we can now move the vertex from 'from' to 'to' 
+        *======================================================================*/
+        graph->mincut -= myedegrees[k].ed-myrinfo->id;
+
+        IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut));
+
+        /* Update pmat to reflect the move of 'i' */
+        pmat[from*nparts+to] += (myrinfo->id-myedegrees[k].ed);
+        pmat[to*nparts+from] += (myrinfo->id-myedegrees[k].ed);
+        if (pmat[from*nparts+to] == 0) {
+          ndoms[from]--;
+          if (ndoms[from]+1 == maxndoms)
+            maxndoms = ndoms[idxamax(nparts, ndoms)];
+        }
+        if (pmat[to*nparts+from] == 0) {
+          ndoms[to]--;
+          if (ndoms[to]+1 == maxndoms)
+            maxndoms = ndoms[idxamax(nparts, ndoms)];
+        }
+
+        /* Update where, weight, and ID/ED information of the vertex you moved */
+        where[i] = to;
+        INC_DEC(pwgts[to], pwgts[from], vwgt);
+        myrinfo->ed += myrinfo->id-myedegrees[k].ed;
+        SWAP(myrinfo->id, myedegrees[k].ed, j);
+        if (myedegrees[k].ed == 0) 
+          myedegrees[k] = myedegrees[--myrinfo->ndegrees];
+        else
+          myedegrees[k].pid = from;
+
+        if (myrinfo->ed-myrinfo->id < 0)
+          BNDDelete(nbnd, bndind, bndptr, i);
+
+        /* Update the degrees of adjacent vertices */
+        for (j=xadj[i]; j<xadj[i+1]; j++) {
+          ii = adjncy[j];
+          me = where[ii];
+
+          myrinfo = graph->rinfo+ii;
+          if (myrinfo->edegrees == NULL) {
+            myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree;
+            ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii];
+          }
+          myedegrees = myrinfo->edegrees;
+
+          ASSERT(CheckRInfo(myrinfo));
+
+          if (me == from) {
+            INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]);
+
+            if (myrinfo->ed-myrinfo->id >= 0 && bndptr[ii] == -1)
+              BNDInsert(nbnd, bndind, bndptr, ii);
+          }
+          else if (me == to) {
+            INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]);
+
+            if (myrinfo->ed-myrinfo->id < 0 && bndptr[ii] != -1)
+              BNDDelete(nbnd, bndind, bndptr, ii);
+          }
+
+          /* Remove contribution from the .ed of 'from' */
+          if (me != from) {
+            for (k=0; k<myrinfo->ndegrees; k++) {
+              if (myedegrees[k].pid == from) {
+                if (myedegrees[k].ed == adjwgt[j])
+                  myedegrees[k] = myedegrees[--myrinfo->ndegrees];
+                else
+                  myedegrees[k].ed -= adjwgt[j];
+                break;
+              }
+            }
+          }
+
+          /* Add contribution to the .ed of 'to' */
+          if (me != to) {
+            for (k=0; k<myrinfo->ndegrees; k++) {
+              if (myedegrees[k].pid == to) {
+                myedegrees[k].ed += adjwgt[j];
+                break;
+              }
+            }
+            if (k == myrinfo->ndegrees) {
+              myedegrees[myrinfo->ndegrees].pid = to;
+              myedegrees[myrinfo->ndegrees++].ed = adjwgt[j];
+            }
+          }
+
+          /* Update pmat to reflect the move of 'i' for domains other than 'from' and 'to' */
+          if (me != from && me != to) {
+            pmat[me*nparts+from] -= adjwgt[j];
+            pmat[from*nparts+me] -= adjwgt[j];
+            if (pmat[me*nparts+from] == 0) {
+              ndoms[me]--;
+              if (ndoms[me]+1 == maxndoms)
+                maxndoms = ndoms[idxamax(nparts, ndoms)];
+            }
+            if (pmat[from*nparts+me] == 0) {
+              ndoms[from]--;
+              if (ndoms[from]+1 == maxndoms)
+                maxndoms = ndoms[idxamax(nparts, ndoms)];
+            }
+
+            if (pmat[me*nparts+to] == 0) {
+              ndoms[me]++;
+              if (ndoms[me] > maxndoms) {
+                printf("You just increased the maxndoms: %d %d\n", ndoms[me], maxndoms);
+                maxndoms = ndoms[me];
+              }
+            }
+            if (pmat[to*nparts+me] == 0) {
+              ndoms[to]++;
+              if (ndoms[to] > maxndoms) {
+                printf("You just increased the maxndoms: %d %d\n", ndoms[to], maxndoms);
+                maxndoms = ndoms[to];
+              }
+            }
+            pmat[me*nparts+to] += adjwgt[j];
+            pmat[to*nparts+me] += adjwgt[j];
+          }
+
+          ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]);
+          ASSERT(CheckRInfo(myrinfo));
+
+        }
+        nmoves++;
+      }
+    }
+
+    graph->nbnd = nbnd;
+
+    IFSET(ctrl->dbglvl, DBG_REFINE,
+       printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %5d, Vol: %5d, %d\n",
+               pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)],
+               1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, 
+               graph->mincut, ComputeVolume(graph, where), idxsum(nparts, ndoms)));
+
+    if (graph->mincut == oldcut)
+      break;
+  }
+
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nvtxs);
+}
+
+
+
+/*************************************************************************
+* This function performs k-way refinement
+**************************************************************************/
+void Greedy_KWayEdgeBalanceMConn(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses)
+{
+  int i, ii, iii, j, jj, k, l, pass, nvtxs, nbnd, tvwgt, myndegrees, oldgain, gain, nmoves; 
+  int from, me, to, oldcut, vwgt, maxndoms, nadd;
+  idxtype *xadj, *adjncy, *adjwgt;
+  idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *moved, *itpwgts;
+  idxtype *phtable, *pmat, *pmatptr, *ndoms;
+  EDegreeType *myedegrees;
+  RInfoType *myrinfo;
+  PQueueType queue;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  bndind = graph->bndind;
+  bndptr = graph->bndptr;
+
+  where = graph->where;
+  pwgts = graph->pwgts;
+  
+  pmat = ctrl->wspace.pmat;
+  phtable = idxwspacemalloc(ctrl, nparts);
+  ndoms = idxwspacemalloc(ctrl, nparts);
+
+  ComputeSubDomainGraph(graph, nparts, pmat, ndoms);
+
+
+  /* Setup the weight intervals of the various subdomains */
+  minwgt =  idxwspacemalloc(ctrl, nparts);
+  maxwgt = idxwspacemalloc(ctrl, nparts);
+  itpwgts = idxwspacemalloc(ctrl, nparts);
+  tvwgt = idxsum(nparts, pwgts);
+  ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt));
+
+  for (i=0; i<nparts; i++) {
+    itpwgts[i] = tpwgts[i]*tvwgt;
+    maxwgt[i] = tpwgts[i]*tvwgt*ubfactor;
+    minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor);
+  }
+
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  moved = idxwspacemalloc(ctrl, nvtxs);
+
+  PQueueInit(ctrl, &queue, nvtxs, graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]);
+
+  IFSET(ctrl->dbglvl, DBG_REFINE,
+     printf("Partitions: [%6d %6d]-[%6d %6d], Balance: %5.3f, Nv-Nb[%6d %6d]. Cut: %6d [B]\n",
+             pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], 
+             1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd,
+             graph->mincut));
+
+  for (pass=0; pass<npasses; pass++) {
+    ASSERT(ComputeCut(graph, where) == graph->mincut);
+
+    /* Check to see if things are out of balance, given the tolerance */
+    for (i=0; i<nparts; i++) {
+      if (pwgts[i] > maxwgt[i])
+        break;
+    }
+    if (i == nparts) /* Things are balanced. Return right away */
+      break;
+
+    PQueueReset(&queue);
+    idxset(nvtxs, -1, moved);
+
+    oldcut = graph->mincut;
+    nbnd = graph->nbnd;
+
+    RandomPermute(nbnd, perm, 1);
+    for (ii=0; ii<nbnd; ii++) {
+      i = bndind[perm[ii]];
+      PQueueInsert(&queue, i, graph->rinfo[i].ed - graph->rinfo[i].id);
+      moved[i] = 2;
+    }
+
+    maxndoms = ndoms[idxamax(nparts, ndoms)];
+
+    for (nmoves=0;;) {
+      if ((i = PQueueGetMax(&queue)) == -1) 
+        break;
+      moved[i] = 1;
+
+      myrinfo = graph->rinfo+i;
+      from = where[i];
+      vwgt = graph->vwgt[i];
+
+      if (pwgts[from]-vwgt < minwgt[from]) 
+        continue;   /* This cannot be moved! */
+
+      myedegrees = myrinfo->edegrees;
+      myndegrees = myrinfo->ndegrees;
+
+      /* Determine the valid domains */
+      for (j=0; j<myndegrees; j++) {
+        to = myedegrees[j].pid;
+        phtable[to] = 1;
+        pmatptr = pmat + to*nparts;
+        for (nadd=0, k=0; k<myndegrees; k++) {
+          if (k == j)
+            continue;
+
+          l = myedegrees[k].pid;
+          if (pmatptr[l] == 0) {
+            if (ndoms[l] > maxndoms-1) {
+              phtable[to] = 0;
+              nadd = maxndoms;
+              break;
+            }
+            nadd++;
+          }
+        }
+        if (ndoms[to]+nadd > maxndoms)
+          phtable[to] = 0;
+      }
+
+      for (k=0; k<myndegrees; k++) {
+        to = myedegrees[k].pid;
+        if (!phtable[to])
+          continue;
+        if (pwgts[to]+vwgt <= maxwgt[to] || itpwgts[from]*(pwgts[to]+vwgt) <= itpwgts[to]*pwgts[from]) 
+          break;
+      }
+      if (k == myndegrees)
+        continue;  /* break out if you did not find a candidate */
+
+      for (j=k+1; j<myndegrees; j++) {
+        to = myedegrees[j].pid;
+        if (!phtable[to])
+          continue;
+        if (itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid]) 
+          k = j;
+      }
+
+      to = myedegrees[k].pid;
+
+      if (pwgts[from] < maxwgt[from] && pwgts[to] > minwgt[to] && myedegrees[k].ed-myrinfo->id < 0) 
+        continue;
+
+      /*=====================================================================
+      * If we got here, we can now move the vertex from 'from' to 'to' 
+      *======================================================================*/
+      graph->mincut -= myedegrees[k].ed-myrinfo->id;
+
+      IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut));
+
+      /* Update pmat to reflect the move of 'i' */
+      pmat[from*nparts+to] += (myrinfo->id-myedegrees[k].ed);
+      pmat[to*nparts+from] += (myrinfo->id-myedegrees[k].ed);
+      if (pmat[from*nparts+to] == 0) {
+        ndoms[from]--;
+        if (ndoms[from]+1 == maxndoms)
+          maxndoms = ndoms[idxamax(nparts, ndoms)];
+      }
+      if (pmat[to*nparts+from] == 0) {
+        ndoms[to]--;
+        if (ndoms[to]+1 == maxndoms)
+          maxndoms = ndoms[idxamax(nparts, ndoms)];
+      }
+
+
+      /* Update where, weight, and ID/ED information of the vertex you moved */
+      where[i] = to;
+      INC_DEC(pwgts[to], pwgts[from], vwgt);
+      myrinfo->ed += myrinfo->id-myedegrees[k].ed;
+      SWAP(myrinfo->id, myedegrees[k].ed, j);
+      if (myedegrees[k].ed == 0) 
+        myedegrees[k] = myedegrees[--myrinfo->ndegrees];
+      else
+        myedegrees[k].pid = from;
+
+      if (myrinfo->ed == 0)
+        BNDDelete(nbnd, bndind, bndptr, i);
+
+      /* Update the degrees of adjacent vertices */
+      for (j=xadj[i]; j<xadj[i+1]; j++) {
+        ii = adjncy[j];
+        me = where[ii];
+
+        myrinfo = graph->rinfo+ii;
+        if (myrinfo->edegrees == NULL) {
+          myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree;
+          ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii];
+        }
+        myedegrees = myrinfo->edegrees;
+
+        ASSERT(CheckRInfo(myrinfo));
+
+        oldgain = (myrinfo->ed-myrinfo->id);
+
+        if (me == from) {
+          INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]);
+
+          if (myrinfo->ed > 0 && bndptr[ii] == -1)
+            BNDInsert(nbnd, bndind, bndptr, ii);
+        }
+        else if (me == to) {
+          INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]);
+
+          if (myrinfo->ed == 0 && bndptr[ii] != -1)
+            BNDDelete(nbnd, bndind, bndptr, ii);
+        }
+
+        /* Remove contribution from the .ed of 'from' */
+        if (me != from) {
+          for (k=0; k<myrinfo->ndegrees; k++) {
+            if (myedegrees[k].pid == from) {
+              if (myedegrees[k].ed == adjwgt[j])
+                myedegrees[k] = myedegrees[--myrinfo->ndegrees];
+              else
+                myedegrees[k].ed -= adjwgt[j];
+              break;
+            }
+          }
+        }
+
+        /* Add contribution to the .ed of 'to' */
+        if (me != to) {
+          for (k=0; k<myrinfo->ndegrees; k++) {
+            if (myedegrees[k].pid == to) {
+              myedegrees[k].ed += adjwgt[j];
+              break;
+            }
+          }
+          if (k == myrinfo->ndegrees) {
+            myedegrees[myrinfo->ndegrees].pid = to;
+            myedegrees[myrinfo->ndegrees++].ed = adjwgt[j];
+          }
+        }
+
+        /* Update pmat to reflect the move of 'i' for domains other than 'from' and 'to' */
+        if (me != from && me != to) {
+          pmat[me*nparts+from] -= adjwgt[j];
+          pmat[from*nparts+me] -= adjwgt[j];
+          if (pmat[me*nparts+from] == 0) {
+            ndoms[me]--;
+            if (ndoms[me]+1 == maxndoms)
+              maxndoms = ndoms[idxamax(nparts, ndoms)];
+          }
+          if (pmat[from*nparts+me] == 0) {
+            ndoms[from]--;
+            if (ndoms[from]+1 == maxndoms)
+              maxndoms = ndoms[idxamax(nparts, ndoms)];
+          }
+
+          if (pmat[me*nparts+to] == 0) {
+            ndoms[me]++;
+            if (ndoms[me] > maxndoms) {
+              printf("You just increased the maxndoms: %d %d\n", ndoms[me], maxndoms);
+              maxndoms = ndoms[me];
+            }
+          }
+          if (pmat[to*nparts+me] == 0) {
+            ndoms[to]++;
+            if (ndoms[to] > maxndoms) {
+              printf("You just increased the maxndoms: %d %d\n", ndoms[to], maxndoms);
+              maxndoms = ndoms[to];
+            }
+          }
+          pmat[me*nparts+to] += adjwgt[j];
+          pmat[to*nparts+me] += adjwgt[j];
+        }
+
+        /* Update the queue */
+        if (me == to || me == from) { 
+          gain = myrinfo->ed-myrinfo->id;
+          if (moved[ii] == 2) {
+            if (myrinfo->ed > 0)
+              PQueueUpdate(&queue, ii, oldgain, gain);
+            else {
+              PQueueDelete(&queue, ii, oldgain);
+              moved[ii] = -1;
+            }
+          }
+          else if (moved[ii] == -1 && myrinfo->ed > 0) {
+            PQueueInsert(&queue, ii, gain);
+            moved[ii] = 2;
+          }
+        } 
+
+        ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]);
+        ASSERT(CheckRInfo(myrinfo));
+      }
+      nmoves++;
+    }
+
+    graph->nbnd = nbnd;
+
+    IFSET(ctrl->dbglvl, DBG_REFINE,
+       printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, %d\n",
+               pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)],
+               1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, graph->mincut,idxsum(nparts, ndoms)));
+  }
+
+  PQueueFree(ctrl, &queue);
+
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+
+}
+
+
+
+
+/*************************************************************************
+* This function computes the subdomain graph
+**************************************************************************/
+void PrintSubDomainGraph(GraphType *graph, int nparts, idxtype *where)
+{
+  int i, j, k, me, nvtxs, total, max;
+  idxtype *xadj, *adjncy, *adjwgt, *pmat;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  pmat = idxsmalloc(nparts*nparts, 0, "ComputeSubDomainGraph: pmat");
+
+  for (i=0; i<nvtxs; i++) {
+    me = where[i];
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      k = adjncy[j];
+      if (where[k] != me) 
+        pmat[me*nparts+where[k]] += adjwgt[j];
+    }
+  }
+
+  /* printf("Subdomain Info\n"); */
+  total = max = 0;
+  for (i=0; i<nparts; i++) {
+    for (k=0, j=0; j<nparts; j++) {
+      if (pmat[i*nparts+j] > 0)
+        k++;
+    }
+    total += k;
+
+    if (k > max)
+      max = k;
+/*
+    printf("%2d -> %2d  ", i, k);
+    for (j=0; j<nparts; j++) {
+      if (pmat[i*nparts+j] > 0)
+        printf("[%2d %4d] ", j, pmat[i*nparts+j]);
+    }
+    printf("\n");
+*/
+  }
+  printf("Total adjacent subdomains: %d, Max: %d\n", total, max);
+
+  free(pmat);
+}
+
+
+
+/*************************************************************************
+* This function computes the subdomain graph
+**************************************************************************/
+void ComputeSubDomainGraph(GraphType *graph, int nparts, idxtype *pmat, idxtype *ndoms)
+{
+  int i, j, k, me, nvtxs, ndegrees;
+  idxtype *xadj, *adjncy, *adjwgt, *where;
+  RInfoType *rinfo;
+  EDegreeType *edegrees;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+  where = graph->where;
+  rinfo = graph->rinfo;
+
+  idxset(nparts*nparts, 0, pmat);
+
+  for (i=0; i<nvtxs; i++) {
+    if (rinfo[i].ed > 0) {
+      me = where[i];
+      ndegrees = rinfo[i].ndegrees;
+      edegrees = rinfo[i].edegrees;
+
+      k = me*nparts;
+      for (j=0; j<ndegrees; j++) 
+        pmat[k+edegrees[j].pid] += edegrees[j].ed;
+    }
+  }
+
+  for (i=0; i<nparts; i++) {
+    ndoms[i] = 0;
+    for (j=0; j<nparts; j++) {
+      if (pmat[i*nparts+j] > 0)
+        ndoms[i]++;
+    }
+  }
+
+}
+
+
+
+
+
+/*************************************************************************
+* This function computes the subdomain graph
+**************************************************************************/
+void EliminateSubDomainEdges(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts)
+{
+  int i, ii, j, k, me, other, nvtxs, total, max, avg, totalout, nind, ncand, ncand2, target, target2, nadd;
+  int min, move, cpwgt, tvwgt;
+  idxtype *xadj, *adjncy, *vwgt, *adjwgt, *pwgts, *where, *maxpwgt, *pmat, *ndoms, *mypmat, *otherpmat, *ind;
+  KeyValueType *cand, *cand2;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  vwgt = graph->vwgt;
+  adjwgt = graph->adjwgt;
+
+  where = graph->where;
+  pwgts = graph->pwgts;  /* We assume that this is properly initialized */
+
+  maxpwgt = idxwspacemalloc(ctrl, nparts);
+  ndoms = idxwspacemalloc(ctrl, nparts);
+  otherpmat = idxwspacemalloc(ctrl, nparts);
+  ind = idxwspacemalloc(ctrl, nvtxs);
+  pmat = ctrl->wspace.pmat;
+
+  cand = (KeyValueType *)GKmalloc(nparts*sizeof(KeyValueType), "EliminateSubDomainEdges: cand");
+  cand2 = (KeyValueType *)GKmalloc(nparts*sizeof(KeyValueType), "EliminateSubDomainEdges: cand");
+
+  /* Compute the pmat matrix and ndoms */
+  ComputeSubDomainGraph(graph, nparts, pmat, ndoms);
+
+
+  /* Compute the maximum allowed weight for each domain */
+  tvwgt = idxsum(nparts, pwgts);
+  for (i=0; i<nparts; i++)
+    maxpwgt[i] = 1.25*tpwgts[i]*tvwgt;
+
+
+  /* Get into the loop eliminating subdomain connections */
+  for (;;) {
+    total = idxsum(nparts, ndoms);
+    avg = total/nparts;
+    max = ndoms[idxamax(nparts, ndoms)];
+
+    /* printf("Adjacent Subdomain Stats: Total: %3d, Max: %3d, Avg: %3d [%5d]\n", total, max, avg, idxsum(nparts*nparts, pmat)); */
+
+    if (max < 1.4*avg)
+      break;
+
+    me = idxamax(nparts, ndoms);
+    mypmat = pmat + me*nparts;
+    totalout = idxsum(nparts, mypmat);
+
+    /*printf("Me: %d, TotalOut: %d,\n", me, totalout);*/
+
+    /* Sort the connections according to their cut */
+    for (ncand2=0, i=0; i<nparts; i++) {
+      if (mypmat[i] > 0) {
+        cand2[ncand2].key = mypmat[i];
+        cand2[ncand2++].val = i;
+      }
+    }
+    ikeysort(ncand2, cand2);
+
+    move = 0;
+    for (min=0; min<ncand2; min++) {
+      if (cand2[min].key > totalout/(2*ndoms[me])) 
+        break;
+
+      other = cand2[min].val;
+
+      /*printf("\tMinOut: %d to %d\n", mypmat[other], other);*/
+
+      idxset(nparts, 0, otherpmat);
+
+      /* Go and find the vertices in 'other' that are connected in 'me' */
+      for (nind=0, i=0; i<nvtxs; i++) {
+        if (where[i] == other) {
+          for (j=xadj[i]; j<xadj[i+1]; j++) {
+            if (where[adjncy[j]] == me) {
+              ind[nind++] = i;
+              break;
+            }
+          }
+        }
+      }
+
+      /* Go and construct the otherpmat to see where these nind vertices are connected to */
+      for (cpwgt=0, ii=0; ii<nind; ii++) {
+        i = ind[ii];
+        cpwgt += vwgt[i];
+
+        for (j=xadj[i]; j<xadj[i+1]; j++) 
+          otherpmat[where[adjncy[j]]] += adjwgt[j];
+      }
+      otherpmat[other] = 0;
+
+      for (ncand=0, i=0; i<nparts; i++) {
+        if (otherpmat[i] > 0) {
+          cand[ncand].key = -otherpmat[i];
+          cand[ncand++].val = i;
+        }
+      }
+      ikeysort(ncand, cand);
+
+      /* 
+       * Go through and the select the first domain that is common with 'me', and
+       * does not increase the ndoms[target] higher than my ndoms, subject to the
+       * maxpwgt constraint. Traversal is done from the mostly connected to the least.
+       */
+      target = target2 = -1;
+      for (i=0; i<ncand; i++) {
+        k = cand[i].val;
+
+        if (mypmat[k] > 0) {
+          if (pwgts[k] + cpwgt > maxpwgt[k])  /* Check if balance will go off */
+            continue;
+
+          for (j=0; j<nparts; j++) {
+            if (otherpmat[j] > 0 && ndoms[j] >= ndoms[me]-1 && pmat[nparts*j+k] == 0)
+              break;
+          }
+          if (j == nparts) { /* No bad second level effects */
+            for (nadd=0, j=0; j<nparts; j++) {
+              if (otherpmat[j] > 0 && pmat[nparts*k+j] == 0)
+                nadd++;
+            }
+
+            /*printf("\t\tto=%d, nadd=%d, %d\n", k, nadd, ndoms[k]);*/
+            if (target2 == -1 && ndoms[k]+nadd < ndoms[me]) {
+              target2 = k;
+            }
+            if (nadd == 0) {
+              target = k;
+              break;
+            }
+          }
+        }
+      }
+      if (target == -1 && target2 != -1)
+        target = target2;
+
+      if (target == -1) {
+        /* printf("\t\tCould not make the move\n");*/
+        continue;
+      }
+
+      /*printf("\t\tMoving to %d\n", target);*/
+
+      /* Update the partition weights */
+      INC_DEC(pwgts[target], pwgts[other], cpwgt);
+
+      MoveGroupMConn(ctrl, graph, ndoms, pmat, nparts, target, nind, ind);
+
+      move = 1;
+      break;
+    }
+
+    if (move == 0)
+      break;
+  }
+
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nvtxs);
+
+  GKfree(&cand, &cand2, LTERM);
+}
+
+
+/*************************************************************************
+* This function moves a collection of vertices and updates their rinfo
+**************************************************************************/
+void MoveGroupMConn(CtrlType *ctrl, GraphType *graph, idxtype *ndoms, idxtype *pmat,
+                    int nparts, int to, int nind, idxtype *ind)
+{
+  int i, ii, iii, j, jj, k, l, nvtxs, nbnd, myndegrees; 
+  int from, me;
+  idxtype *xadj, *adjncy, *adjwgt;
+  idxtype *where, *bndptr, *bndind;
+  EDegreeType *myedegrees;
+  RInfoType *myrinfo;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  where = graph->where;
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+
+  nbnd = graph->nbnd;
+
+  for (iii=0; iii<nind; iii++) {
+    i = ind[iii];
+    from = where[i];
+
+    myrinfo = graph->rinfo+i;
+    if (myrinfo->edegrees == NULL) {
+      myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree;
+      ctrl->wspace.cdegree += xadj[i+1]-xadj[i];
+      myrinfo->ndegrees = 0;
+    }
+    myedegrees = myrinfo->edegrees;
+
+    /* find the location of 'to' in myrinfo or create it if it is not there */
+    for (k=0; k<myrinfo->ndegrees; k++) {
+      if (myedegrees[k].pid == to)
+        break;
+    }
+    if (k == myrinfo->ndegrees) {
+      myedegrees[k].pid = to;
+      myedegrees[k].ed = 0;
+      myrinfo->ndegrees++;
+    }
+
+    graph->mincut -= myedegrees[k].ed-myrinfo->id;
+
+    /* Update pmat to reflect the move of 'i' */
+    pmat[from*nparts+to] += (myrinfo->id-myedegrees[k].ed);
+    pmat[to*nparts+from] += (myrinfo->id-myedegrees[k].ed);
+    if (pmat[from*nparts+to] == 0) 
+      ndoms[from]--;
+    if (pmat[to*nparts+from] == 0) 
+      ndoms[to]--;
+
+    /* Update where, weight, and ID/ED information of the vertex you moved */
+    where[i] = to;
+    myrinfo->ed += myrinfo->id-myedegrees[k].ed;
+    SWAP(myrinfo->id, myedegrees[k].ed, j);
+    if (myedegrees[k].ed == 0) 
+      myedegrees[k] = myedegrees[--myrinfo->ndegrees];
+    else
+      myedegrees[k].pid = from;
+
+    if (myrinfo->ed-myrinfo->id < 0 && bndptr[i] != -1)
+      BNDDelete(nbnd, bndind, bndptr, i);
+
+    /* Update the degrees of adjacent vertices */
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      ii = adjncy[j];
+      me = where[ii];
+
+      myrinfo = graph->rinfo+ii;
+      if (myrinfo->edegrees == NULL) {
+        myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree;
+        ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii];
+      }
+      myedegrees = myrinfo->edegrees;
+
+      ASSERT(CheckRInfo(myrinfo));
+
+      if (me == from) {
+        INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]);
+
+        if (myrinfo->ed-myrinfo->id >= 0 && bndptr[ii] == -1)
+          BNDInsert(nbnd, bndind, bndptr, ii);
+      }
+      else if (me == to) {
+        INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]);
+
+        if (myrinfo->ed-myrinfo->id < 0 && bndptr[ii] != -1)
+          BNDDelete(nbnd, bndind, bndptr, ii);
+      }
+
+      /* Remove contribution from the .ed of 'from' */
+      if (me != from) {
+        for (k=0; k<myrinfo->ndegrees; k++) {
+          if (myedegrees[k].pid == from) {
+            if (myedegrees[k].ed == adjwgt[j])
+              myedegrees[k] = myedegrees[--myrinfo->ndegrees];
+            else
+              myedegrees[k].ed -= adjwgt[j];
+            break;
+          }
+        }
+      }
+
+      /* Add contribution to the .ed of 'to' */
+      if (me != to) {
+        for (k=0; k<myrinfo->ndegrees; k++) {
+          if (myedegrees[k].pid == to) {
+            myedegrees[k].ed += adjwgt[j];
+            break;
+          }
+        }
+        if (k == myrinfo->ndegrees) {
+          myedegrees[myrinfo->ndegrees].pid = to;
+          myedegrees[myrinfo->ndegrees++].ed = adjwgt[j];
+        }
+      }
+
+      /* Update pmat to reflect the move of 'i' for domains other than 'from' and 'to' */
+      if (me != from && me != to) {
+        pmat[me*nparts+from] -= adjwgt[j];
+        pmat[from*nparts+me] -= adjwgt[j];
+        if (pmat[me*nparts+from] == 0) 
+          ndoms[me]--;
+        if (pmat[from*nparts+me] == 0) 
+          ndoms[from]--;
+
+        if (pmat[me*nparts+to] == 0) 
+          ndoms[me]++;
+        if (pmat[to*nparts+me] == 0) 
+          ndoms[to]++;
+
+        pmat[me*nparts+to] += adjwgt[j];
+        pmat[to*nparts+me] += adjwgt[j];
+      }
+
+      ASSERT(CheckRInfo(myrinfo));
+    }
+
+    ASSERT(CheckRInfo(graph->rinfo+i));
+  }
+
+  graph->nbnd = nbnd;
+
+}
+
+
+
+
+/*************************************************************************
+* This function finds all the connected components induced by the 
+* partitioning vector in wgraph->where and tries to push them around to 
+* remove some of them
+**************************************************************************/
+void EliminateComponents(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor)
+{
+  int i, ii, j, jj, k, me, nvtxs, tvwgt, first, last, nleft, ncmps, cwgt, other, target, deltawgt;
+  idxtype *xadj, *adjncy, *vwgt, *adjwgt, *where, *pwgts, *maxpwgt;
+  idxtype *cpvec, *touched, *perm, *todo, *cind, *cptr, *npcmps;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  vwgt = graph->vwgt;
+  adjwgt = graph->adjwgt;
+
+  where = graph->where;
+  pwgts = graph->pwgts;
+
+  touched = idxset(nvtxs, 0, idxwspacemalloc(ctrl, nvtxs));
+  cptr = idxwspacemalloc(ctrl, nvtxs);
+  cind = idxwspacemalloc(ctrl, nvtxs);
+  perm = idxwspacemalloc(ctrl, nvtxs);
+  todo = idxwspacemalloc(ctrl, nvtxs);
+  maxpwgt = idxwspacemalloc(ctrl, nparts);
+  cpvec = idxwspacemalloc(ctrl, nparts);
+  npcmps = idxset(nparts, 0, idxwspacemalloc(ctrl, nparts));
+
+  for (i=0; i<nvtxs; i++) 
+    perm[i] = todo[i] = i;
+
+  /* Find the connected componends induced by the partition */
+  ncmps = -1;
+  first = last = 0;
+  nleft = nvtxs;
+  while (nleft > 0) {
+    if (first == last) { /* Find another starting vertex */
+      cptr[++ncmps] = first;
+      ASSERT(touched[todo[0]] == 0);
+      i = todo[0];
+      cind[last++] = i;
+      touched[i] = 1;
+      me = where[i];
+      npcmps[me]++;
+    }
+
+    i = cind[first++];
+    k = perm[i];
+    j = todo[k] = todo[--nleft];
+    perm[j] = k;
+
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      k = adjncy[j];
+      if (where[k] == me && !touched[k]) {
+        cind[last++] = k;
+        touched[k] = 1;
+      }
+    }
+  }
+  cptr[++ncmps] = first;
+
+  /* printf("I found %d components, for this %d-way partition\n", ncmps, nparts); */
+
+  if (ncmps > nparts) { /* There are more components than processors */
+    /* First determine the max allowed load imbalance */
+    tvwgt = idxsum(nparts, pwgts);
+    for (i=0; i<nparts; i++)
+      maxpwgt[i] = ubfactor*tpwgts[i]*tvwgt;
+
+    deltawgt = 5;
+
+    for (i=0; i<ncmps; i++) {
+      me = where[cind[cptr[i]]];  /* Get the domain of this component */
+      if (npcmps[me] == 1)
+        continue;  /* Skip it because it is contigous */
+
+      /*printf("Trying to move %d from %d\n", i, me); */
+
+      /* Determine the weight of the block to be moved and abort if too high */
+      for (cwgt=0, j=cptr[i]; j<cptr[i+1]; j++) 
+        cwgt += vwgt[cind[j]];
+
+      if (cwgt > .30*pwgts[me])
+        continue;  /* Skip the component if it is over 30% of the weight */
+
+      /* Determine the connectivity */
+      idxset(nparts, 0, cpvec);
+      for (j=cptr[i]; j<cptr[i+1]; j++) {
+        ii = cind[j];
+        for (jj=xadj[ii]; jj<xadj[ii+1]; jj++) 
+          cpvec[where[adjncy[jj]]] += adjwgt[jj];
+      }
+      cpvec[me] = 0;
+
+      target = -1;
+      for (j=0; j<nparts; j++) {
+        if (cpvec[j] > 0 && (cwgt < deltawgt || pwgts[j] + cwgt < maxpwgt[j])) {
+          if (target == -1 || cpvec[target] < cpvec[j])
+            target = j;
+        }
+      }
+
+      /* printf("\tMoving it to %d [%d]\n", target, cpvec[target]);*/
+
+      if (target != -1) {
+        /* Assign all the vertices of 'me' to 'target' and update data structures */
+        INC_DEC(pwgts[target], pwgts[me], cwgt);
+        npcmps[me]--;
+
+        MoveGroup(ctrl, graph, nparts, target, i, cptr, cind);
+      }
+    }
+
+  }
+
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nparts);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+  idxwspacefree(ctrl, nvtxs);
+
+}
+
+
+/*************************************************************************
+* This function moves a collection of vertices and updates their rinfo
+**************************************************************************/
+void MoveGroup(CtrlType *ctrl, GraphType *graph, int nparts, int to, int gid, idxtype *ptr, idxtype *ind)
+{
+  int i, ii, iii, j, jj, k, l, nvtxs, nbnd, myndegrees; 
+  int from, me;
+  idxtype *xadj, *adjncy, *adjwgt;
+  idxtype *where, *bndptr, *bndind;
+  EDegreeType *myedegrees;
+  RInfoType *myrinfo;
+
+  nvtxs = graph->nvtxs;
+  xadj = graph->xadj;
+  adjncy = graph->adjncy;
+  adjwgt = graph->adjwgt;
+
+  where = graph->where;
+  bndptr = graph->bndptr;
+  bndind = graph->bndind;
+
+  nbnd = graph->nbnd;
+
+  for (iii=ptr[gid]; iii<ptr[gid+1]; iii++) {
+    i = ind[iii];
+    from = where[i];
+
+    myrinfo = graph->rinfo+i;
+    if (myrinfo->edegrees == NULL) {
+      myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree;
+      ctrl->wspace.cdegree += xadj[i+1]-xadj[i];
+      myrinfo->ndegrees = 0;
+    }
+    myedegrees = myrinfo->edegrees;
+
+    /* find the location of 'to' in myrinfo or create it if it is not there */
+    for (k=0; k<myrinfo->ndegrees; k++) {
+      if (myedegrees[k].pid == to)
+        break;
+    }
+    if (k == myrinfo->ndegrees) {
+      myedegrees[k].pid = to;
+      myedegrees[k].ed = 0;
+      myrinfo->ndegrees++;
+    }
+
+    graph->mincut -= myedegrees[k].ed-myrinfo->id;
+
+
+    /* Update where, weight, and ID/ED information of the vertex you moved */
+    where[i] = to;
+    myrinfo->ed += myrinfo->id-myedegrees[k].ed;
+    SWAP(myrinfo->id, myedegrees[k].ed, j);
+    if (myedegrees[k].ed == 0) 
+      myedegrees[k] = myedegrees[--myrinfo->ndegrees];
+    else
+      myedegrees[k].pid = from;
+
+    if (myrinfo->ed-myrinfo->id < 0 && bndptr[i] != -1)
+      BNDDelete(nbnd, bndind, bndptr, i);
+
+    /* Update the degrees of adjacent vertices */
+    for (j=xadj[i]; j<xadj[i+1]; j++) {
+      ii = adjncy[j];
+      me = where[ii];
+
+      myrinfo = graph->rinfo+ii;
+      if (myrinfo->edegrees == NULL) {
+        myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree;
+        ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii];
+      }
+      myedegrees = myrinfo->edegrees;
+
+      ASSERT(CheckRInfo(myrinfo));
+
+      if (me == from) {
+        INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]);
+
+        if (myrinfo->ed-myrinfo->id >= 0 && bndptr[ii] == -1)
+          BNDInsert(nbnd, bndind, bndptr, ii);
+      }
+      else if (me == to) {
+        INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]);
+
+        if (myrinfo->ed-myrinfo->id < 0 && bndptr[ii] != -1)
+          BNDDelete(nbnd, bndind, bndptr, ii);
+      }
+
+      /* Remove contribution from the .ed of 'from' */
+      if (me != from) {
+        for (k=0; k<myrinfo->ndegrees; k++) {
+          if (myedegrees[k].pid == from) {
+            if (myedegrees[k].ed == adjwgt[j])
+              myedegrees[k] = myedegrees[--myrinfo->ndegrees];
+            else
+              myedegrees[k].ed -= adjwgt[j];
+            break;
+          }
+        }
+      }
+
+      /* Add contribution to the .ed of 'to' */
+      if (me != to) {
+        for (k=0; k<myrinfo->ndegrees; k++) {
+          if (myedegrees[k].pid == to) {
+            myedegrees[k].ed += adjwgt[j];
+            break;
+          }
+        }
+        if (k == myrinfo->ndegrees) {
+          myedegrees[myrinfo->ndegrees].pid = to;
+          myedegrees[myrinfo->ndegrees++].ed = adjwgt[j];
+        }
+      }
+
+      ASSERT(CheckRInfo(myrinfo));
+    }
+
+    ASSERT(CheckRInfo(graph->rinfo+i));
+  }
+
+  graph->nbnd = nbnd;
+
+}
+
diff --git a/Metis/timing.c b/Metis/timing.c
new file mode 100644
index 0000000000..5495f92732
--- /dev/null
+++ b/Metis/timing.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * timing.c
+ *
+ * This file contains routines that deal with timing Metis
+ *
+ * Started 7/24/97
+ * George
+ *
+ * $Id: timing.c,v 1.1 2005-09-07 14:36:46 remacle Exp $
+ *
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function clears the timers
+**************************************************************************/
+void InitTimers(CtrlType *ctrl)
+{
+  cleartimer(ctrl->TotalTmr);
+  cleartimer(ctrl->InitPartTmr);
+  cleartimer(ctrl->MatchTmr);
+  cleartimer(ctrl->ContractTmr);
+  cleartimer(ctrl->CoarsenTmr);
+  cleartimer(ctrl->UncoarsenTmr);
+  cleartimer(ctrl->RefTmr);
+  cleartimer(ctrl->ProjectTmr);
+  cleartimer(ctrl->SplitTmr);
+  cleartimer(ctrl->SepTmr);
+  cleartimer(ctrl->AuxTmr1);
+  cleartimer(ctrl->AuxTmr2);
+  cleartimer(ctrl->AuxTmr3);
+  cleartimer(ctrl->AuxTmr4);
+  cleartimer(ctrl->AuxTmr5);
+  cleartimer(ctrl->AuxTmr6);
+}
+
+
+
+/*************************************************************************
+* This function prints the various timers
+**************************************************************************/
+void PrintTimers(CtrlType *ctrl)
+{
+  printf("\nTiming Information -------------------------------------------------");
+  printf("\n Multilevel: \t\t %7.3f", gettimer(ctrl->TotalTmr));
+  printf("\n     Coarsening: \t\t %7.3f", gettimer(ctrl->CoarsenTmr));
+  printf("\n            Matching: \t\t\t %7.3f", gettimer(ctrl->MatchTmr));
+  printf("\n            Contract: \t\t\t %7.3f", gettimer(ctrl->ContractTmr));
+  printf("\n     Initial Partition: \t %7.3f", gettimer(ctrl->InitPartTmr));
+  printf("\n   Construct Separator: \t %7.3f", gettimer(ctrl->SepTmr));
+  printf("\n     Uncoarsening: \t\t %7.3f", gettimer(ctrl->UncoarsenTmr));
+  printf("\n          Refinement: \t\t\t %7.3f", gettimer(ctrl->RefTmr));
+  printf("\n          Projection: \t\t\t %7.3f", gettimer(ctrl->ProjectTmr));
+  printf("\n     Splitting: \t\t %7.3f", gettimer(ctrl->SplitTmr));
+  printf("\n          AUX1: \t\t %7.3f", gettimer(ctrl->AuxTmr1));
+  printf("\n          AUX2: \t\t %7.3f", gettimer(ctrl->AuxTmr2));
+  printf("\n          AUX3: \t\t %7.3f", gettimer(ctrl->AuxTmr3));
+  printf("\n********************************************************************\n");
+}
+
+
+/*************************************************************************
+* This function returns the seconds
+**************************************************************************/
+double seconds(void)
+{
+  return((double) clock()/CLOCKS_PER_SEC);
+}
+
+
diff --git a/Metis/util.c b/Metis/util.c
new file mode 100644
index 0000000000..36eef2f938
--- /dev/null
+++ b/Metis/util.c
@@ -0,0 +1,519 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * util.c
+ *
+ * This function contains various utility routines
+ *
+ * Started 9/28/95
+ * George
+ *
+ * $Id: util.c,v 1.1 2005-09-07 14:36:46 remacle Exp $
+ */
+
+#include <metis.h>
+
+
+/*************************************************************************
+* This function prints an error message and exits
+**************************************************************************/
+void errexit(char *f_str,...)
+{
+  va_list argp;
+  char out1[256], out2[256];
+
+  va_start(argp, f_str);
+  vsprintf(out1, f_str, argp);
+  va_end(argp);
+
+  sprintf(out2, "Error! %s", out1);
+
+  fprintf(stdout, out2);
+  fflush(stdout);
+
+  abort();
+}
+
+
+
+#ifndef DMALLOC
+/*************************************************************************
+* The following function allocates an array of integers
+**************************************************************************/
+int *imalloc(int n, char *msg)
+{
+  if (n == 0)
+    return NULL;
+
+  return (int *)GKmalloc(sizeof(int)*n, msg);
+}
+
+
+/*************************************************************************
+* The following function allocates an array of integers
+**************************************************************************/
+idxtype *idxmalloc(int n, char *msg)
+{
+  if (n == 0)
+    return NULL;
+
+  return (idxtype *)GKmalloc(sizeof(idxtype)*n, msg);
+}
+
+
+/*************************************************************************
+* The following function allocates an array of float 
+**************************************************************************/
+float *fmalloc(int n, char *msg)
+{
+  if (n == 0)
+    return NULL;
+
+  return (float *)GKmalloc(sizeof(float)*n, msg);
+}
+
+
+/*************************************************************************
+* The follwoing function allocates an array of integers
+**************************************************************************/
+int *ismalloc(int n, int ival, char *msg)
+{
+  if (n == 0)
+    return NULL;
+
+  return iset(n, ival, (int *)GKmalloc(sizeof(int)*n, msg));
+}
+
+
+
+/*************************************************************************
+* The follwoing function allocates an array of integers
+**************************************************************************/
+idxtype *idxsmalloc(int n, idxtype ival, char *msg)
+{
+  if (n == 0)
+    return NULL;
+
+  return idxset(n, ival, (idxtype *)GKmalloc(sizeof(idxtype)*n, msg));
+}
+
+
+/*************************************************************************
+* This function is my wrapper around malloc
+**************************************************************************/
+void *GKmalloc(int nbytes, char *msg)
+{
+  void *ptr;
+
+  if (nbytes == 0)
+    return NULL;
+
+  ptr = (void *)malloc(nbytes);
+  if (ptr == NULL) 
+    errexit("***Memory allocation failed for %s. Requested size: %d bytes", msg, nbytes);
+
+  return ptr;
+}
+#endif
+
+/*************************************************************************
+* This function is my wrapper around free, allows multiple pointers    
+**************************************************************************/
+void GKfree(void **ptr1,...)
+{
+  va_list plist;
+  void **ptr;
+
+  if (*ptr1 != NULL)
+    free(*ptr1);
+  *ptr1 = NULL;
+
+  va_start(plist, ptr1);
+
+  /* while ((int)(ptr = va_arg(plist, void **)) != -1) { */
+  while ((ptr = va_arg(plist, void **)) != LTERM) {
+    if (*ptr != NULL)
+      free(*ptr);
+    *ptr = NULL;
+  }
+
+  va_end(plist);
+}            
+
+
+/*************************************************************************
+* These functions set the values of a vector
+**************************************************************************/
+int *iset(int n, int val, int *x)
+{
+  int i;
+
+  for (i=0; i<n; i++)
+    x[i] = val;
+
+  return x;
+}
+
+
+/*************************************************************************
+* These functions set the values of a vector
+**************************************************************************/
+idxtype *idxset(int n, idxtype val, idxtype *x)
+{
+  int i;
+
+  for (i=0; i<n; i++)
+    x[i] = val;
+
+  return x;
+}
+
+
+/*************************************************************************
+* These functions set the values of a vector
+**************************************************************************/
+float *sset(int n, float val, float *x)
+{
+  int i;
+
+  for (i=0; i<n; i++)
+    x[i] = val;
+
+  return x;
+}
+
+
+
+/*************************************************************************
+* These functions return the index of the maximum element in a vector
+**************************************************************************/
+int iamax(int n, int *x)
+{
+  int i, max=0;
+
+  for (i=1; i<n; i++)
+    max = (x[i] > x[max] ? i : max);
+
+  return max;
+}
+
+
+/*************************************************************************
+* These functions return the index of the maximum element in a vector
+**************************************************************************/
+int idxamax(int n, idxtype *x)
+{
+  int i, max=0;
+
+  for (i=1; i<n; i++)
+    max = (x[i] > x[max] ? i : max);
+
+  return max;
+}
+
+/*************************************************************************
+* These functions return the index of the maximum element in a vector
+**************************************************************************/
+int idxamax_strd(int n, idxtype *x, int incx)
+{
+  int i, max=0;
+
+  n *= incx;
+  for (i=incx; i<n; i+=incx)
+    max = (x[i] > x[max] ? i : max);
+
+  return max/incx;
+}
+
+
+
+/*************************************************************************
+* These functions return the index of the maximum element in a vector
+**************************************************************************/
+int samax(int n, float *x)
+{
+  int i, max=0;
+
+  for (i=1; i<n; i++)
+    max = (x[i] > x[max] ? i : max);
+
+  return max;
+}
+
+/*************************************************************************
+* These functions return the index of the almost maximum element in a vector
+**************************************************************************/
+int samax2(int n, float *x)
+{
+  int i, max1, max2;
+
+  if (x[0] > x[1]) {
+    max1 = 0;
+    max2 = 1;
+  }
+  else {
+    max1 = 1;
+    max2 = 0;
+  }
+
+  for (i=2; i<n; i++) {
+    if (x[i] > x[max1]) {
+      max2 = max1;
+      max1 = i;
+    }
+    else if (x[i] > x[max2])
+      max2 = i;
+  }
+
+  return max2;
+}
+
+
+/*************************************************************************
+* These functions return the index of the minimum element in a vector
+**************************************************************************/
+int idxamin(int n, idxtype *x)
+{
+  int i, min=0;
+
+  for (i=1; i<n; i++)
+    min = (x[i] < x[min] ? i : min);
+
+  return min;
+}
+
+
+/*************************************************************************
+* These functions return the index of the minimum element in a vector
+**************************************************************************/
+int samin(int n, float *x)
+{
+  int i, min=0;
+
+  for (i=1; i<n; i++)
+    min = (x[i] < x[min] ? i : min);
+
+  return min;
+}
+
+
+/*************************************************************************
+* This function sums the entries in an array
+**************************************************************************/
+int idxsum(int n, idxtype *x)
+{
+  int i, sum = 0;
+
+  for (i=0; i<n; i++)
+    sum += x[i];
+
+  return sum;
+}
+
+
+/*************************************************************************
+* This function sums the entries in an array
+**************************************************************************/
+int idxsum_strd(int n, idxtype *x, int incx)
+{
+  int i, sum = 0;
+
+  for (i=0; i<n; i++, x+=incx) {
+    sum += *x;
+  }
+
+  return sum;
+}
+
+
+/*************************************************************************
+* This function sums the entries in an array
+**************************************************************************/
+void idxadd(int n, idxtype *x, idxtype *y)
+{
+  for (n--; n>=0; n--)
+    y[n] += x[n];
+}
+
+
+/*************************************************************************
+* This function sums the entries in an array
+**************************************************************************/
+int charsum(int n, char *x)
+{
+  int i, sum = 0;
+
+  for (i=0; i<n; i++)
+    sum += x[i];
+
+  return sum;
+}
+
+/*************************************************************************
+* This function sums the entries in an array
+**************************************************************************/
+int isum(int n, int *x)
+{
+  int i, sum = 0;
+
+  for (i=0; i<n; i++)
+    sum += x[i];
+
+  return sum;
+}
+
+/*************************************************************************
+* This function sums the entries in an array
+**************************************************************************/
+float ssum(int n, float *x)
+{
+  int i;
+  float sum = 0.0;
+
+  for (i=0; i<n; i++)
+    sum += x[i];
+
+  return sum;
+}
+
+/*************************************************************************
+* This function sums the entries in an array
+**************************************************************************/
+float ssum_strd(int n, float *x, int incx)
+{
+  int i;
+  float sum = 0.0;
+
+  for (i=0; i<n; i++, x+=incx)
+    sum += *x;
+
+  return sum;
+}
+
+/*************************************************************************
+* This function sums the entries in an array
+**************************************************************************/
+void sscale(int n, float alpha, float *x)
+{
+  int i;
+
+  for (i=0; i<n; i++)
+    x[i] *= alpha;
+}
+
+
+/*************************************************************************
+* This function computes a 2-norm
+**************************************************************************/
+float snorm2(int n, float *v)
+{
+  int i;
+  float partial = 0;
+ 
+  for (i = 0; i<n; i++)
+    partial += v[i] * v[i];
+
+  return sqrt(partial);
+}
+
+
+
+/*************************************************************************
+* This function computes a 2-norm
+**************************************************************************/
+float sdot(int n, float *x, float *y)
+{
+  int i;
+  float partial = 0;
+ 
+  for (i = 0; i<n; i++)
+    partial += x[i] * y[i];
+
+  return partial;
+}
+
+
+/*************************************************************************
+* This function computes a 2-norm
+**************************************************************************/
+void saxpy(int n, float alpha, float *x, int incx, float *y, int incy)
+{
+  int i;
+ 
+  for (i=0; i<n; i++, x+=incx, y+=incy) 
+    *y += alpha*(*x);
+}
+
+
+
+
+/*************************************************************************
+* This file randomly permutes the contents of an array.
+* flag == 0, don't initialize perm
+* flag == 1, set p[i] = i 
+**************************************************************************/
+void RandomPermute(int n, idxtype *p, int flag)
+{
+  int i, u, v;
+  idxtype tmp;
+
+  if (flag == 1) {
+    for (i=0; i<n; i++)
+      p[i] = i;
+  }
+
+  if (n <= 4)
+    return;
+
+  for (i=0; i<n; i+=16) {
+    u = RandomInRangeFast(n-4);
+    v = RandomInRangeFast(n-4);
+    SWAP(p[v], p[u], tmp);
+    SWAP(p[v+1], p[u+1], tmp);
+    SWAP(p[v+2], p[u+2], tmp);
+    SWAP(p[v+3], p[u+3], tmp);
+  }
+}
+
+
+
+/*************************************************************************
+* This function returns true if the a is a power of 2
+**************************************************************************/
+int ispow2(int a)
+{
+  for (; a%2 != 1; a = a>>1);
+  return (a > 1 ? 0 : 1);
+}
+
+
+/*************************************************************************
+* This function initializes the random number generator
+**************************************************************************/
+void InitRandom(int seed)
+{
+  if (seed == -1) {
+#ifndef __VC__
+    srand48(7654321L);  
+#endif
+    srand(4321);  
+  }
+  else {
+#ifndef __VC__
+    srand48(seed);  
+#endif
+    srand(seed);  
+  }
+}
+
+/*************************************************************************
+* This function returns the log2(x)
+**************************************************************************/
+int log2(int a)
+{
+  int i;
+
+  for (i=1; a > 1; i++, a = a>>1);
+  return i-1;
+}
+
diff --git a/Parser/OpenFile.cpp b/Parser/OpenFile.cpp
index e1915ab7e6..24a7cd0f4c 100644
--- a/Parser/OpenFile.cpp
+++ b/Parser/OpenFile.cpp
@@ -1,4 +1,4 @@
-// $Id: OpenFile.cpp,v 1.81 2005-07-04 15:07:41 remacle Exp $
+// $Id: OpenFile.cpp,v 1.82 2005-09-07 14:36:46 remacle Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -50,6 +50,7 @@ extern Mesh *THEM, M;
 extern Context_T CTX;
 
 extern  void BDS_To_Mesh(Mesh *m);
+extern  void BDS_To_Mesh_2(Mesh *m);
 
 void FixRelativePath(char *in, char *out){
   if(in[0] == '/' || in[0] == '\\' || (strlen(in)>2 && in[1] == ':')){
diff --git a/configure b/configure
index 872d69f195..c63e65b069 100755
--- a/configure
+++ b/configure
@@ -855,6 +855,7 @@ Optional Features:
   --enable-triangle       compile Triangle if available (default=yes)
   --enable-netgen         compile Netgen if available (default=yes)
   --enable-ann            compile ANN if available (default=yes)
+  --enable-metis          compile METIS if available (default=yes)
   --enable-tetgen         compile Tetgen if available (default=yes)
   --enable-matheval       compile MathEval if available (default=yes)
   --enable-jpeg           enable JPEG support (default=yes)
@@ -1388,6 +1389,11 @@ fi;
 if test "${enable_ann+set}" = set; then
   enableval="$enable_ann"
 
+fi;
+# Check whether --enable-metis or --disable-metis was given.
+if test "${enable_metis+set}" = set; then
+  enableval="$enable_metis"
+
 fi;
 # Check whether --enable-tetgen or --disable-tetgen was given.
 if test "${enable_tetgen+set}" = set; then
@@ -3839,6 +3845,54 @@ else
   fi
 fi
 
+echo "$as_me:$LINENO: checking for ./Metis/metis.h" >&5
+echo $ECHO_N "checking for ./Metis/metis.h... $ECHO_C" >&6
+if test "${ac_cv_file___Metis_metis_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  test "$cross_compiling" = yes &&
+  { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5
+echo "$as_me: error: cannot check for file existence when cross compiling" >&2;}
+   { (exit 1); exit 1; }; }
+if test -r "./Metis/metis.h"; then
+  ac_cv_file___Metis_metis_h=yes
+else
+  ac_cv_file___Metis_metis_h=no
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_file___Metis_metis_h" >&5
+echo "${ECHO_T}$ac_cv_file___Metis_metis_h" >&6
+if test $ac_cv_file___Metis_metis_h = yes; then
+  METIS="yes"
+else
+  METIS="no"
+fi
+
+if test "x${METIS}" = "xyes"; then
+  if test "x$enable_metis" != "xno"; then
+     GMSH_DIRS="${GMSH_DIRS} Metis"
+     GMSH_LIBS="${GMSH_LIBS} -lGmshMetis"
+     FLAGS="-DHAVE_METIS ${FLAGS}"
+     echo "********************************************************************"
+     echo "You are building a version of Gmsh that contains METIS, the"
+     echo "Serial Graph Partitioner."
+     echo "Please note that by doing so, you agree with METIS's licensing"
+     echo "requirements stated in ./Metis/Doc/manual.ps."
+     echo "To disable METIS, run configure again with the --disable-metis"
+     echo "option."
+     echo "********************************************************************"
+  fi
+else
+  if test "x$enable-metis" != "xno"; then
+     echo "********************************************************************"
+     echo "If you want to use METIS for doing mesh partitioning, please download METIS from the"
+     echo "author's web site at http://www-users.cs.umn.edu/~karypis/metis/"
+     echo "unpack the archive and copy the Lib Directory in the"
+     echo "./Metis subdirectory. Then run ./configure again."
+     echo "********************************************************************"
+  fi
+fi
+
 echo "$as_me:$LINENO: checking for ./Netgen/libsrc/meshing/meshclass.cpp" >&5
 echo $ECHO_N "checking for ./Netgen/libsrc/meshing/meshclass.cpp... $ECHO_C" >&6
 if test "${ac_cv_file___Netgen_libsrc_meshing_meshclass_cpp+set}" = set; then
diff --git a/configure.in b/configure.in
index fd75e21f05..d4da309bf3 100644
--- a/configure.in
+++ b/configure.in
@@ -1,4 +1,4 @@
-dnl $Id: configure.in,v 1.77 2005-08-31 22:03:26 geuzaine Exp $
+dnl $Id: configure.in,v 1.78 2005-09-07 14:36:44 remacle Exp $
 dnl
 dnl Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 dnl
@@ -72,6 +72,9 @@ AC_ARG_ENABLE(netgen,
 AC_ARG_ENABLE(ann,
               AC_HELP_STRING([--enable-ann],
                              [compile ANN if available (default=yes)]))
+AC_ARG_ENABLE(metis,
+              AC_HELP_STRING([--enable-metis],
+                             [compile METIS if available (default=yes)]))
 AC_ARG_ENABLE(tetgen,
               AC_HELP_STRING([--enable-tetgen],
                              [compile Tetgen if available (default=yes)]))
@@ -283,6 +286,33 @@ else
   fi
 fi
 
+dnl Check if METIS is installed
+AC_CHECK_FILE(./Metis/metis.h, METIS="yes", METIS="no")
+if test "x${METIS}" = "xyes"; then
+  if test "x$enable_metis" != "xno"; then
+     GMSH_DIRS="${GMSH_DIRS} Metis"
+     GMSH_LIBS="${GMSH_LIBS} -lGmshMetis"
+     FLAGS="-DHAVE_METIS ${FLAGS}"
+     echo "********************************************************************"
+     echo "You are building a version of Gmsh that contains METIS, the"
+     echo "Serial Graph Partitioner."
+     echo "Please note that by doing so, you agree with METIS's licensing"
+     echo "requirements stated in ./Metis/Doc/manual.ps."
+     echo "To disable METIS, run configure again with the --disable-metis"
+     echo "option."
+     echo "********************************************************************"
+  fi
+else
+  if test "x$enable-metis" != "xno"; then
+     echo "********************************************************************"
+     echo "If you want to use METIS for doing mesh partitioning, please download METIS from the"
+     echo "author's web site at http://www-users.cs.umn.edu/~karypis/metis/"
+     echo "unpack the archive and copy the Lib Directory in the"
+     echo "./Metis subdirectory. Then run ./configure again."
+     echo "********************************************************************"
+  fi
+fi
+
 dnl Check if Netgen is installed
 AC_CHECK_FILE(./Netgen/libsrc/meshing/meshclass.cpp, NETGEN="yes", NETGEN="no")
 if test "x${NETGEN}" = "xyes"; then
-- 
GitLab