#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <set>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

#include <complex>
typedef complex<double> Point;
static const double INF = 1e+10;

struct Line : public vector<Point> {
  Line() {;}
  Line(Point a, Point b) { push_back(a); push_back(b); }
};

struct Circle {
  Point p;
  double r;
  Circle() {;}
  Circle(Point p, double r) : p(p), r(r) {;}
};

namespace std {
  bool operator<(const Point &lhs, const Point &rhs) {
    return lhs.imag() == rhs.imag() ? lhs.real() < rhs.real() : lhs.imag() < rhs.imag();
  }
}

inline double cross(const Point &a, const Point &b) {
  return imag(conj(a) * b);
}

inline double dot(const Point &a, const Point &b) {
  return real(conj(a) * b);
}

inline int ccw(Point a, Point b, Point c) {
  b -= a;
  c -= a;
  if (cross(b, c) > 0) { return 1; }
  if (cross(b, c) < 0) { return -1; }
  if (dot(b, c) < 0) { return 2; }
  if (norm(b) < norm(c)) { return -2; }
  return 0;
}

bool intersectSP(const Line &s, const Point &p) {
  return abs(s[0] - p) + abs(s[1] - p) - abs(s[1] - s[0]) < EPS;
}

inline bool chmin(double &lhs, const double &rhs) {
  if (lhs - rhs < EPS) { return false; }
  lhs = rhs;
  return true;
}

enum {
  UP = 1,
  RIGHT = 2,
  LEFT = 4
};
typedef double Weight;
struct Edge {
  int type;
  int src;
  int dest;
  Weight weight;
  Edge(int type, int src, int dest, Weight weight) : type(type), src(src), dest(dest), weight(weight) {;}
  bool operator<(const Edge &rhs) const {
    if (weight != rhs.weight) { return weight > rhs.weight; }
    if (src != rhs.src) { return src < rhs.src; }
    return dest < rhs.dest;
  }
};
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;

void PrintMatrix(const Matrix &matrix) {
  for (int y = 0; y < (int)matrix.size(); y++) {
    for (int x = 0; x < (int)matrix[y].size(); x++) {
      printf("%lf ", matrix[y][x]);
    }
    puts("");
  }
}

double dp[4][101][101][101];
int n, k;
double r;
Point ps[110];
int end[3];

struct State {
  int state;
  int pos[3];
  double cost;
  double a;
  void CalcA() {
    a = 0;
    REP(i, k) {
      a += abs(ps[pos[i]] - ps[end[i]]);
    }
  }
  bool operator<(const State &rhs) const {
    return cost + a > rhs.cost + rhs.a;
  }
};


vector<pair<Point, int> > CalcBackest(const State &s) {
  vector<pair<Point, int> > ret;
  REP(i, k) {
    if (s.pos[i] == end[i]) { continue; }
    ret.push_back(make_pair(ps[s.pos[i]], i));
  }
  sort(ret.begin(), ret.end());
  while (ret.size() > 1 && ret.front().first.imag() != ret.back().first.imag()) { ret.pop_back(); }
  return ret;
}

int CalcIndex(const State &s) {
  vector<pair<Point, int> > indexs = CalcBackest(s);
  int rest = indexs.size();
  if (rest == 0) { return -1; }
  if (s.state == 3) {
    return indexs.back().second + 6 + rest * 10;
  }

  if (rest == 1) { return indexs[0].second + rest * 10; }
  if (s.state == 0) { return indexs[0].second + 3 + rest * 10; }
  if (s.state == 1) { return indexs[1].second + 3 + rest * 10; }
  if (s.state == 2) {
    assert(rest == 3);
    return indexs[2].second + 3 + rest * 10;
  }
  assert(false);
  return -1;
}

int CalcState(const Edge &e, const State &s, int next, int prest) {
  REP(i, k) REP(j, i) {
    if (s.pos[i] == s.pos[j]) { return -1; }
  }
  REP(i, k) {
    if (ps[s.pos[i]].imag() > ps[end[i]].imag()) { return -1; }
  }
  int rest = CalcBackest(s).size();
  if (s.state == 3 && prest == 1 && e.type == UP) { return 0; }
  if (s.state == 0 && prest == 1) { return 0; }
  if (s.state < 3 && s.state >= rest) { return 3; }
  if (s.state < 3 && !next) { return s.state; }
  if (s.state < 3) {
    if (s.state + 1 >= rest) { return 3; }
    return s.state + 1;
  }
  return 3;
}

int main() {
  while (scanf("%d %d %lf", &n, &k, &r) > 0) {
    State ini;
    ini.state = 0;
    ini.cost = 0;
    ini.pos[0] = ini.pos[1] = ini.pos[2] = n;
    end[0] = end[1] = end[2] = n;
    REP(i, k) {
      int p;
      scanf("%d", &p);
      ini.pos[i] = p - 1;
    }
    REP(i, k) {
      scanf("%d", &end[i]);
      end[i]--;
    }
    REP(i, n) {
      double x, y;
      scanf("%lf %lf", &x, &y);
      ps[i] = Point(x, y);
    }
    ps[n] = Point(1e+8, 1e+8);
    Graph g(n + 1);
    REP(i, n) {
      g[i].push_back(Edge(UP | LEFT | RIGHT, i, i, 0));
    }
    REP(i, n) REP(j, n) {
      if (i == j) { continue; }
      if (norm(ps[i] - ps[j]) - r * r < EPS && ps[i].imag() <= ps[j].imag()) {
        REP(k, n) {
          if (i == k || j == k) { continue; }
          if (intersectSP(Line(ps[i], ps[j]), ps[k])) { goto next; }
        }
        double d = abs(ps[i] - ps[j]);
        int type = UP;
        if (ps[i].imag() == ps[j].imag()) {
          type = ps[i].real() <= ps[j].real() ? RIGHT : LEFT;
        }
        //cout << i << " " << j << " " << type << endl;
        g[i].push_back(Edge(type, i, j, d));
      }
next:;
    }
    ini.CalcA();
    REP(i, 4) REP(j, 101) REP(k, 101) REP(l, 101) { dp[i][j][k][l] = 1e+100; }
    dp[0][ini.pos[0]][ini.pos[1]][ini.pos[2]] = ini.a;
    priority_queue<State> que;
    que.push(ini);
    while (!que.empty()) {
      State s = que.top();
      que.pop();
      if (s.pos[0] == end[0] && s.pos[1] == end[1] && s.pos[2] == end[2]) { break; }
      int index = CalcIndex(s);
      if (index < 0) { continue; }
      if (dp[s.state][s.pos[0]][s.pos[1]][s.pos[2]] - s.cost - s.a > EPS) { continue; }
      int rest = index / 10;
      assert(rest > 0);
      index %= 10;
      int okType = UP | LEFT | RIGHT;
      if (3 <= index && index <= 6) { okType = RIGHT; }
      if (6 <= index && index < 9) { okType = UP | LEFT; }
      index %= 3;
      //cout << s.state << " " << s.pos[0] << " " << s.pos[1] << " " << (int)s.pos[2] << " " << okType << endl;
      FORIT(it, g[s.pos[index]]) {
        if (!(it->type & okType)) { continue; }
        REP(e, 2) {
          State ns = s;
          ns.cost = s.cost + it->weight;
          ns.pos[index] = it->dest;
          ns.state = CalcState(*it, ns, e, rest);
          ns.CalcA();
          //cout << it->src << " " << it->dest << endl;
          if (ns.state < 0) { continue; }
          if (!chmin(dp[ns.state][ns.pos[0]][ns.pos[1]][ns.pos[2]], ns.cost + ns.a)) { continue; }
          que.push(ns);
        }
      }
    }
    double ans = 1e+100;
    REP(i, 4) { ans = min(ans, dp[i][end[0]][end[1]][end[2]]); }
    if (ans < 1e+100) {
      printf("%.8f\n", ans);
    } else {
      puts("-1");
    }
  }
}

Measured memory_bytes: 0