#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#define LL long long
#define Re register
using namespace std;
int n,m,cnt;
struct Node{
double p_x,p_y;
}a[201];
struct NNN1{
int next,to;
double w;
}edge[800001];
struct Noding{
int id;
double zhi;
bool operator <(const Noding &x) const {
return zhi>x.zhi;
}
};
priority_queue<Noding>q;
int head[201],v[201],road[201],rv[201];
double d[201];
int able[201][201];
inline double Dis(int u,int v){
return sqrt((a[u].p_x-a[v].p_x)*(a[u].p_x-a[v].p_x)+(a[u].p_y-a[v].p_y)*(a[u].p_y-a[v].p_y));
}
inline void add(int u,int v){
Re double ww=Dis(u,v);
edge[++cnt].next=head[u];
edge[cnt].to=v;
edge[cnt].w=ww;
head[u]=cnt;
edge[++cnt].next=head[v];
edge[cnt].to=u;
edge[cnt].w=ww;
head[v]=cnt;
}
inline int read(){
register int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
int top=0;
inline void DIJ(int flag){
for(int i=1;i<=n;++i) d[i]=0x3f3f3f3f;
memset(v,0,sizeof(v));
memset(rv,0,sizeof(rv));
d[1]=0;
q.push((Noding){1,0});
while(!q.empty()){
Re Noding gxa=q.top();
q.pop();
Re int u=gxa.id;
if(v[u]) continue;
v[u]=1;
Re int c=0;
for(int i=head[u];i;i=edge[i].next){
Re int tx=edge[i].to;
Re double tw=edge[i].w;
if(flag&&!able[u][tx]) continue;
if(!v[tx]&&d[u]+tw<d[tx]){
c++;
d[tx]=d[u]+tw;
if(!flag&&c==1) road[++top]=u;
q.push((Noding){tx,d[tx]});
}
}
}
while(!q.empty()) q.pop();
}
int main(){
n=read(),m=read();
for(int i=1;i<=n;++i){
a[i].p_x=(double)read()*1.0;
a[i].p_y=(double)read()*1.0;
}
for(int i=1;i<=m;++i){
Re int u=read(),v=read();
add(u,v);
able[u][v]=1;
able[v][u]=1;
}
DIJ(0);
if(road[top]!=n) road[++top]=n;
Re int yuan=d[n];
Re double ans=0x3f3f3f3f3f3f3f3f;
for(int i=1;i<top;++i){
able[road[i]][road[i+1]]=0;
able[road[i+1]][road[i]]=0;
DIJ(1);
ans=(ans<d[n])?ans:d[n];
able[road[i]][road[i+1]]=1;
able[road[i+1]][road[i]]=1;
}
if(yuan==ans) printf("-1");
else printf("%.2lf",ans);
return 0;
}