#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#define ll long long
#define INF 0x7fffffff/2
#define pll pair<double,ll>
#define mp make_pair
using namespace std;
const int MN=10005;
ll n,m,tot,x[MN],y[MN],u,v,head[MN];
double dis[MN];
bool vis[MN];
struct edge{ll nxt,to;double w;}e[MN<<2];
struct node{ll pos;double w;};
priority_queue<pll,vector<pll>,greater<pll> > q;
ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
double gs(ll x, ll y, ll xx, ll yy){return (double)sqrt((x-xx)*(x-xx)+(y-yy)*(y-yy));}
void add(ll u, ll v){e[++tot].nxt=head[u];head[u]=tot;e[tot].to=v;e[tot].w=gs(x[u],y[u],x[v],y[v]);}
void dijkstra(ll x){
for(int i=1; i<=n; i++) dis[i]=INF,vis[i]=false;
dis[x]=0;q.push(mp(dis[x],x));
while(q.size()){
ll u=q.top().second;q.pop();
if(vis[u]) continue;
vis[u]=true;
for(int i=head[u]; i; i=e[i].nxt){
ll v=e[i].to;double w=e[i].w;
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
q.push(mp(dis[v],v));
}
}
}
}
bool operator < (node a, node b){return a.w+dis[a.pos]>b.w+dis[b.pos];}
ll A(ll res){
priority_queue<node> q;
q.push((node){1,0});
while(q.size()){
node z=q.top();q.pop();
if(z.pos==n) if(!(--res)){
printf("%.2lf",z.w);
return 0;
}
for(int i=head[z.pos]; i; i=e[i].nxt) q.push((node){e[i].to,z.w+e[i].w});
}
return res;
}
int main(){
n=read();m=read();
for(int i=1; i<=n; i++) x[i]=read(),y[i]=read();
for(int i=1; i<=m; i++){u=read();v=read();add(u,v);add(v,u);}
dijkstra(n);
if(A(2ll)) printf("-1");
return 0;
}