Problem: We have a flat panel with two holes. Pins are nailed on its surface. From the back of the panel, a string comes out through one of the holes to the surface. The string is then laid on the surface in a form of a polygonal chain, and goes out to the panel's back through the other hole. Initially, the string does not touch any pins.

Figures F-1, F-2, and F-3 show three example layouts of holes, pins and strings. In each layout, white squares and circles denote holes and pins, respectively. A polygonal chain of solid segments denotes the string.

<image>
Figure F-1: An example layout of holes, pins and a string

<image>
Figure F-2: An example layout of holes, pins and a string

<image>
Figure F-3: An example layout of holes, pins and a string

When we tie a pair of equal weight stones to the both ends of the string, the stones slowly straighten the string until there is no loose part. The string eventually forms a different polygonal chain as it is obstructed by some of the pins. (There are also cases when the string is obstructed by no pins, though.)

The string does not hook itself while being straightened. A fully tightened string thus draws a polygonal chain on the surface of the panel, whose vertices are the positions of some pins with the end vertices at the two holes. The layouts in Figures F-1, F-2, and F-3 result in the respective polygonal chains in Figures F-4, F-5, and F-6. Write a program that calculates the length of the tightened polygonal chain.

<image>
Figure F-4: Tightened polygonal chains from the example in Figure F-1.

<image>
Figure F-5: Tightened polygonal chains from the example in Figure F-2.

<image>
Figure F-6: Tightened polygonal chains from the example in Figure F-3.

Note that the strings, pins and holes are thin enough so that you can ignore their diameters.

Input

The input consists of multiple datasets, followed by a line containing two zeros separated by a space. Each dataset gives the initial shape of the string (i.e., the positions of holes and vertices) and the positions of pins in the following format.

> m n
>  x1 y1
>  ...
>  xl yl
>

The first line has two integers m and n (2 ≤ m ≤ 100, 0 ≤ n ≤ 100), representing the number of vertices including two holes that give the initial string shape (m) and the number of pins (n). Each of the following l = m + n lines has two integers xi and yi (0 ≤ xi ≤ 1000, 0 ≤ yi ≤ 1000), representing a position Pi = (xi ,yi ) on the surface of the panel.

* Positions P1, ..., Pm give the initial shape of the string; i.e., the two holes are at P1 and Pm , and the string's shape is a polygonal chain whose vertices are Pi (i = 1, ..., m), in this order.
* Positions Pm+1, ..., Pm+n are the positions of the pins.


Note that no two points are at the same position. No three points are exactly on a straight line.

Output

For each dataset, the length of the part of the tightened string that remains on the surface of the panel should be output in a line. No extra characters should appear in the output.

No lengths in the output should have an error greater than 0.001.

Sample Input


6 16
5 4
11 988
474 975
459 16
985 12
984 982
242 227
140 266
45 410
92 570
237 644
370 567
406 424
336 290
756 220
634 251
511 404
575 554
726 643
868 571
907 403
845 283
10 4
261 196
943 289
859 925
56 822
112 383
514 0
1000 457
514 1000
0 485
233 224
710 242
850 654
485 915
140 663
26 5
0 953
180 0
299 501
37 301
325 124
162 507
84 140
913 409
635 157
645 555
894 229
598 223
783 514
765 137
599 445
695 126
859 462
599 312
838 167
708 563
565 258
945 283
251 454
125 111
28 469
1000 1000
185 319
717 296
9 315
372 249
203 528
15 15
200 247
859 597
340 134
967 247
421 623
1000 427
751 1000
102 737
448 0
978 510
556 907
0 582
627 201
697 963
616 608
345 819
810 809
437 706
702 695
448 474
605 474
329 355
691 350
816 231
313 216
864 360
772 278
756 747
529 639
513 525
0 0


Output for the Sample Input


2257.0518296609
3609.92159564177
2195.83727086364
3619.77160684813






Example

Input

6 16
5 4
11 988
474 975
459 16
985 12
984 982
242 227
140 266
45 410
92 570
237 644
370 567
406 424
336 290
756 220
634 251
511 404
575 554
726 643
868 571
907 403
845 283
10 4
261 196
943 289
859 925
56 822
112 383
514 0
1000 457
514 1000
0 485
233 224
710 242
850 654
485 915
140 663
26 5
0 953
180 0
299 501
37 301
325 124
162 507
84 140
913 409
635 157
645 555
894 229
598 223
783 514
765 137
599 445
695 126
859 462
599 312
838 167
708 563
565 258
945 283
251 454
125 111
28 469
1000 1000
185 319
717 296
9 315
372 249
203 528
15 15
200 247
859 597
340 134
967 247
421 623
1000 427
751 1000
102 737
448 0
978 510
556 907
0 582
627 201
697 963
616 608
345 819
810 809
437 706
702 695
448 474
605 474
329 355
691 350
816 231
313 216
864 360
772 278
756 747
529 639
513 525
0 0


Output

2257.0518296609
3609.92159564177
2195.83727086364
3619.77160684813

Solution (in CPP):

Solution:
#include<complex>
#include<vector>
#include<iostream>
#include<stack>
#include<cstdlib>
#include<fstream>
#include<cmath>
#include<map>
#include<cassert>
#include<iomanip>

enum CCW{FRONT=0x01,RIGHT=0x02,BACK=0x04,LEFT=0x08,OVER=0x10};
#define sc second
#define fr first

#define REP(i,n) for(int i = 0; i < (int)(n); ++i)

using namespace std;

typedef long double elem;
typedef complex<elem> point, vec;
typedef pair<point, point> line, hline, seg, pp;

const elem infty = 1e40;
const elem eps = 1.0e-11;
const elem pi = acos(-1.0);
point base(0,0);
inline elem Round(elem a)
{
  return (elem)floor(eps+round(a));
}
bool eq(elem a, elem b){ return abs(a-b) < eps; }
bool eqv(vec a, vec b){ return eq( abs(b-a),0); }
bool far(point a, point b){ return abs(b-a)>0; }
bool near(point a, point b){ return abs(b-a)<=0; }
elem dot(vec a, vec b){ return (a.real() * b.real() + a.imag() * b.imag() ); }
elem cross(vec a, vec b){ return ( a.real() * b.imag() - a.imag() * b.real() ); }
elem dist(point a, point b){ return abs(a-b); }
elem dist_l(line l, point x){ return abs(cross(l.sc-l.fr,x-l.fr)) / abs(l.sc-l.fr); }
elem dist_seg(seg s, point x)
{
  if( dot(s.sc-s.fr,x-s.fr)<0 ) return abs(x-s.fr);
  if( dot(s.fr-s.sc,x-s.sc)<0 ) return abs(x-s.sc);
  return dist_l(s,x);
}
vec uvec(vec a){ return a / abs(a); }
vec nmr(vec a){ return a * vec(0,-1); }
vec nml(vec a){ return a * vec(0,1); }
vec unmr(vec a){ return uvec( nmr(a) ); }
vec unml(vec a){ return uvec( nml(a) ); }

inline int ccw(const point &a, point b, point x){
  b -= a;
  x -= a;
  if( eq(cross(b,x),0.0) && dot(b,x) < 0 ) return BACK;
  if( eq(cross(b,x),0.0) && abs(b) < abs(x) ) return FRONT;
  if( eq(cross(b,x),0.0) ) return OVER;
  if( cross(b,x) > 0 ) return LEFT;
  if( cross(b,x) < 0 ) return RIGHT;
}

inline bool intersectedSS(const seg &a, const seg &b)
{
  int cwaf=ccw(a.fr,a.sc,b.fr);
  int cwbf=ccw(b.fr,b.sc,a.fr);
  int cwas=ccw(a.fr,a.sc,b.sc);
  int cwbs=ccw(b.fr,b.sc,a.sc);
  if( cwaf==OVER || cwas==OVER || cwbf==OVER || cwbs==OVER ) return true;
  return ( cwaf | cwas ) == (LEFT|RIGHT) && ( cwbf | cwbs ) == (LEFT|RIGHT);
}

bool intersectedLL(line a, line b){ return !eq( cross(a.sc-a.fr,b.sc-b.fr), 0.0 ); }

point intersectionSS(seg a, seg b)
{
  elem d1 = dist_l(b,a.fr);
  elem d2 = dist_l(b,a.sc);
  return a.fr + ( d1 / (d1 + d2 ) ) * (a.sc-a.fr);
}
point intersectionLL(line a, line b)
{
  vec va = a.sc - a.fr;
  vec vb = b.sc - b.fr;
  return a.fr + va * ( cross(vb, b.fr - a.fr) / cross(vb,va) );
}

bool intersectionLL(line a, line b, point &ret){
  return intersectedLL( a, b ) ? ret = intersectionLL( a, b ), true : false;
}
bool intersectionLH(line a, hline b, point &ret){
  point tmp;
  return intersectionLL(a,b,tmp) ? ( ccw(b.fr,b.sc,tmp)&(OVER|FRONT) ? ret=tmp, true : false ) : false;
}
bool intersectionLS(line l, seg s, point &ret){
  point tmp;
  return intersectionLL(l,s,tmp) ? ( ccw(s.fr,s.sc,tmp)&OVER ? ret=tmp, true : false ) : false;
}
bool intersectionHH(hline a, hline b, point &ret){
  point tmp;
  return intersectionLL(a,b,tmp) ? ( ccw(a.fr,a.sc,tmp)&(OVER|FRONT)&&ccw(b.fr,b.sc,tmp)&(OVER|FRONT) ? ret = tmp, true : false ) : false;
}
bool intersectionHS(hline a, seg s, point &ret){
  point tmp;
  return intersectionLS(a,s,tmp) ? ( ccw(a.fr,a.sc,tmp)&(OVER|FRONT) ? ret = tmp, true : false ) : false;
}
bool intersectionSS(seg a, seg b, point &ret){
  return intersectedSS(a,b) ? ret = intersectionSS(a,b), true : false;
}

struct triangle{
  vector<point> p;
  triangle():p(3,point(0,0)){}
  triangle(point a,point b,point c){p.push_back(a);p.push_back(b);p.push_back(c);}
  bool contains(point t)const{
    int ccw01=ccw(p[0],p[1],t),ccw02=ccw(p[1],p[2],t),ccw03=ccw(p[2],p[0],t);
    return ccw01==ccw02&&ccw02==ccw03;
  }
};

point getHasMaximumDot(point base1, point base2, const vector<point> &vp)
{
  vec u = uvec(base2 - base1);
  int i0 = -1;
  elem maximumDot = -10;
  for(int i = 0; i < (int)vp.size(); ++i){
    vec v = uvec(vp[i] - base1);
    elem d = dot(u,v);
    if( !(-1<=d&&d<=1) ){
      //cout << u << ' ' << v << endl;
      //assert(-1<=d&&d<=1);
    }
    if( d >= maximumDot){
      maximumDot = d;
      i0 = i;
    }
  }
  //assert(i0>=0);
  return vp[i0];
}

struct StringP{
  point p;
  bool fixed;
  vector<char> state;
  StringP(){}
  StringP(point ip, bool ifixed, vector<char> istate):p(ip),fixed(ifixed),state(istate.begin(),istate.end()){}
};

void printStrings(const vector<StringP> &V)
{
  cout << "PROGRESSING: STRING POINTS :"<<endl;
  for(int i = 0; i < (int)V.size(); ++i){
    cout << V[i].p << ' '  << V[i].fixed << ' ';
    for(int j = 0; j < (int)V[i].state.size(); ++j){
      cout << V[i].state[j];
    }
    cout << endl;
  }
  cout << "---------------------" << endl;
}

int tightenUp(vector<StringP> &V)
{
  if(V.size()<=2)return -1;
  for(int i = 1; i < (int)V.size()-1; ++i){
    StringP &a = V[i-1];
    StringP &b = V[i];
    StringP &c = V[i+1];

    int cw = ccw(a.p,b.p,c.p);
    //assert(cw&(RIGHT|LEFT|OVER|FRONT));
    if( cw == OVER ){
      //assert(near(a.p,c.p));
    }
    
    if( cw == RIGHT ){
      if( b.state.size() == 1 ){
	if( b.state.front()=='R' ){
	  b.fixed = false;
	  return i;
	}
      }
    }else if( cw == LEFT ){
      if( b.state.size() == 1 ){
	if( b.state.front()=='L' ){
	  b.fixed = false;
	  return i;
	}
      }
    }
  }
  return -1;
}

bool fixNext(vector<StringP> &str,
	     int &now,
	     const vector<point> &pins)
{ 
  if(now<=0||now>=(int)str.size()-1||(int)str.size()<=2){++now;return false;}
  if( str[now].fixed ){
    ++now;
    return false;
  }

  point sa = str[now-1].p;
  point sb = str[now].p;
  point sc = str[now+1].p;
  
  //cout << now << ' ' << sa << ' ' << sb << ' ' << sc << endl;
  //assert(ccw(sa,sb,sc)&(LEFT|RIGHT|FRONT));
  if(ccw(sa,sb,sc)&(OVER|FRONT|BACK)){
    //str.erase(str.begin()+now);
    now=0;
    return false;
  }
  triangle tri(sa,sb,sc);
  vector<point> in;
  for(int i = 0; i < (int)pins.size(); ++i){
    if(tri.contains( pins[i] )){
      in.push_back(pins[i]);
    }
  }

  if( in.size() == 0 ){
    if( now > 1 ){
      point prepre = str[now-2].p;
      seg s(sb,sc);
      line ls(sa,prepre);
      point dam;
      if(intersectionLS(ls,s,dam)&&ccw(sa,prepre,dam)&(OVER|FRONT)){
	int cw = ccw(prepre,sa,sb);
	//assert(cw&(RIGHT|LEFT|OVER));
	if( cw==RIGHT ){
	  if( str[now-1].state.back() == 'l' ){
	    str[now-1].state.pop_back();
	  }else{
	    str[now-1].state.push_back('r');
	  }
	}else if( cw==LEFT ){
	  if( str[now-1].state.back() == 'r' ){
	    str[now-1].state.pop_back();
	  }else{
	    str[now-1].state.push_back('l');
	  }
	}else if( cw==OVER ){
	  int cwc = ccw(prepre,sa,sc);
	  //assert(cwc&(RIGHT|LEFT));
	  if( (str[now-1].state.front() == 'L' || str[now-1].state.size()>1) && cwc == RIGHT ){
	    if( str[now-1].state.back() == 'r' ){
	      str[now-1].state.pop_back();
	    }else{
	      str[now-1].state.push_back('l');
	    }
	  }else if( (str[now-1].state.front() == 'R' || str[now-1].state.size()>1) && cwc == LEFT ){
	    if( str[now-1].state.back() == 'l' ){
	      str[now-1].state.pop_back();
	    }else{
	      str[now-1].state.push_back('r');
	    }
	  }
	}
      }
    }
    str.erase(str.begin()+now);
    return true;
  }else{
    point nextFixed = getHasMaximumDot( sa, sb, in );
    int cw = ccw(sa,nextFixed,sb);
    line l(sa,nextFixed);
    seg s(sb,sc);
    point is;

    intersectionLS(l,s,is);
    //assert(
    //assert(far(is,s.first)&&far(is,s.second));

    str[now]=StringP(is,false,vector<char>(0));

    //assert(ccw(sa,nextFixed,is)==FRONT);
    //assert(cw&(RIGHT|LEFT));

    if( now > 1 ){
      point prepre = str[now-2].p;
      seg s(sb,is);
      line ls(sa,prepre);
      point dam;
      if(intersectionLS(ls,s,dam)&&ccw(sa,prepre,dam)&(OVER|FRONT)){
	int cw = ccw(prepre,sa,sb);
	//assert(cw&(RIGHT|LEFT|OVER));
	if( cw==RIGHT ){
	  if( str[now-1].state.back() == 'l' ){
	    str[now-1].state.pop_back();
	  }else{
	    str[now-1].state.push_back('r');
	  }
	}else if( cw==LEFT ){
	  if( str[now-1].state.back() == 'r' ){
	    str[now-1].state.pop_back();
	  }else{
	    str[now-1].state.push_back('l');
	  }
	}else if( cw==OVER ){
	  int cwc = ccw(prepre,sa,is);
	  //assert(cwc&(RIGHT|LEFT));
	  if( (str[now-1].state.front() == 'L' || str[now-1].state.size()>1) && cwc == RIGHT ){
	    if( str[now-1].state.back() == 'r' ){
	      str[now-1].state.pop_back();
	    }else{
	      str[now-1].state.push_back('l');
	    }
	  }else if( (str[now-1].state.front() == 'R' || str[now-1].state.size()>1) && cwc == LEFT ){
	    if( str[now-1].state.back() == 'l' ){
	      str[now-1].state.pop_back();
	    }else{
	      str[now-1].state.push_back('r');
	    }
	  }
	}
      }
    }

    if( cw == RIGHT ){
      str.insert( str.begin()+now, StringP(nextFixed,true,vector<char>(1,'R')));
    }else if( cw == LEFT ){
      str.insert( str.begin()+now, StringP(nextFixed,true,vector<char>(1,'L')));
    }
    return true;
  }
}

point roundPoint(point p){
  return point(Round(p.real()),Round(p.imag()));
}

double getLength(const vector<StringP> &V){
  double ret = 0;
  for(int i = 0; i < (int)V.size()-1; ++i){
    ret += abs(roundPoint(V[i].p)-roundPoint(V[i+1].p));
  }
  return ret;
}
/*
inline void drawLine(ofstream &of, point a, point b){
  of << "line("<<a.real()<<","<<a.imag()<<","<<b.real()<<","<<b.imag()<<");"<<endl;
}

inline void drawPoint(ofstream &of, point a){
  drawLine(of,a,a+point(2,2));
}
*/
int main(){
  //ofstream ofs("vis");
  while(true){
    int m,n;
    vector<point> pins;
    vector<StringP> str;

    cin >> m >> n;
    if(m==0&&n==0)break;
    for(int i = 0; i < m; ++i){
      elem x,y;
      cin >> x >> y;
      str.push_back(StringP(point(x,y),false,vector<char>(0)));
    }
    for(int j = 0; j < n; ++j){
      elem x,y;
      cin >> x >> y;
      //pins.push_back(point(x,y));
      pins.push_back(point(x+0.0017,y+0.0022));
      pins.push_back(point(x-0.0011,y+0.0035));
      pins.push_back(point(x+0.0019,y-0.0043));
      pins.push_back(point(x-0.0023,y-0.0027));
    }
    str.front().fixed = true;
    str.back().fixed = true;
    str.front().state.push_back('X');
    str.back().state.push_back('X');

    int now = 0;
    int next;
    while(now<(int)str.size()){
      fixNext(str,now,pins);
      next= tightenUp(str);
      if( next >= 0 ) now = next;
    }
    
    /*
    cout << "FIXED POINTS :"<<endl;
    for(int i = 0; i < (int)str.size(); ++i){
      cout << str[i].p << endl;
    }
    */

    cout << fixed << setprecision(11) << getLength(str) << endl;
  }
  return 0;
}