#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
int const maxn=45*1000,maxm=130*1000,maxc=15;
struct edge{int x,y;};
// edges::init changes the representation of the graph
// given by N, number of vertices, and E, array of edges,
// into N, number of vertices, and A,I, adjacency lists.
namespace edges
{
int N; // number of vertices
int M; // number of edges
edge E[maxm]; // edges
int A[maxm*2]; // A[i], i=I[x]..I[x+1]-1 are (read next line)
int I[maxn+1]; // neighbours of vertex x;
void init_I()
{ int i,a,b;
for(i=0;N>i;++i){I[i]=0;}
for(i=0;M>i;++i){++I[E[i].x];++I[E[i].y];}
a=I[0];I[0]=0;for(i=1;N>=i;++i){b=I[i];I[i]=I[i-1]+a;a=b;}
}
void init_A()
{ int i;
for(i=0;M>i;++i){A[I[E[i].x]++]=E[i].y;A[I[E[i].y]++]=E[i].x;}
}
void init()
{init_I();init_A();init_I();}
};
// biconnected::process computes the biconnected components
// for the graph represented by edges::N,edges::A, and edges::I
namespace biconnected
{
edge E[maxm]; // stack of edges
int T; // top of stack E
edge C[maxn*maxc]; // C[j], j=I[i]..I[i+1]-1, i=0..K-1 are (read next line)
int I[1+maxn]; // edges of biconnected component i
int K; // number of biconnected components
int A[maxn]; // A[i]==1, i is an articulation point; A[i]==0 otherwise
int R; // root of the DFS
int U; // update : detect if root is articulation point
int P[maxn]; // parent of vertex x in the DFS tree
int D[maxn]; // depth of vertex x in the DFS tree
int L[maxn]; // lowpoint of vertex x in the DFS
void add_component(int tx,int ty)
{ int s=I[K],x,y;
do
{ x=E[T].x;y=E[T].y;
C[s].x=x;C[s].y=y;
++s;--T;
}
while((x!=tx)||(y!=ty));
++K;I[K]=s;
}
void add_articulation_point(int x)
{ if(x!=R)
{A[x]=1;}
else
{ if(1==U)
{A[x]=1;}
U=min(U+1,2);
}
}
void DFS(int x)
{ int i=edges::I[x],t=edges::I[x+1],y;
while(i<t)
{ y=edges::A[i++];
if(-1==P[y])
{ D[y]=D[x]+1;L[y]=D[y];P[y]=x;
++T;E[T].x=x;E[T].y=y;
DFS(y);
L[x]=min(L[x],L[y]);
if(L[y]>=D[x])
{ add_component(x,y);
add_articulation_point(x);
}
}
else
{ if((D[x]>D[y])&&(y!=P[x]))
{++T;E[T].x=x;E[T].y=y;}
L[x]=min(L[x],D[y]);
}
}
}
void process()
{ int i,N=edges::N;
K=0;I[K]=0;T=-1;
for(i=0;N>i;++i){P[i]=-1;}
for(i=0;N>i;++i){A[i]=0;}
for(i=0;N>i;++i)
{ if(-1==P[i])
{ P[i]=i;D[i]=0;L[i]=D[i];R=i;U=0;DFS(i);
}
}
}
void print_components()
{ int i,j;
printf("%d components!\n",K);
for(i=0;K>i;++i)
{ printf("component %d :",1+i);
for(j=I[i];I[i+1]>j;++j)
{printf(" %d,%d ;",1+C[j].x,1+C[j].y);}
printf(" #\n");
}
}
void print_articulation_points()
{ printf("articulation points:");
int i,N=edges::N;
for(i=0;N>i;++i)
{ if(0!=A[i])
{printf(" %d ;", 1+i);}
}
printf(" #\n");
}
}
// forest::process builds the forest with nodes
// biconnected and articulation points
namespace forest
{
int N; // number of vertices
int n; // vertices from 0..n-1 are components; from n to N-1 are articulation points
int V[2*maxn]; // vertices: 0<=V[i] : V[i] biconnected component; 0>V[i]: -V[i]-1 articulation
int E[2*maxn-1][2]; // edges (biconnected component, articulation point)
int A[2*(2*maxn-1)]; // adjacency lists
int I[2*maxn+1]; // A[j], I[x]<=j<=I[x+1]-1, x=0..2*maxn-1, adjacency list for V[x]
int J[2*maxn]; // J[x] - next free position in A for x
int L[maxn]; // Label articulation points;Label graph nodes in component nodes
int F[maxn]; // articulation point is free to add edge to for current component!
void process()
{ N=0;
int i,j,m,c,a,s,t,x,y;
// build vertex set
for(i=0;biconnected::K>i;++i){V[N++]=i;}
n=N;
for(i=0;edges::N>i;++i)
{ if(biconnected::A[i]){V[N++]=i;} }
// build labels for articulation points
for(i=0;edges::N>i;++i){L[i]=-1;}
for(i=n;N>i;++i){L[V[i]]=i;}
// build edge set
m=0;
for(i=0;n>i;++i)
{ c=V[i];
for(j=n;N>j;++j){F[V[j]]=1;}
s=biconnected::I[c];
t=biconnected::I[c+1];
while(s<t)
{ x=biconnected::C[s].x;
y=biconnected::C[s].y;
++s;
if(-1!=L[x])
{ if(F[x])
{E[m][0]=c;E[m][1]=L[x];++m;F[x]=0;}
}
if(-1!=L[y])
{ if(F[x])
{E[m][0]=c;E[m][1]=L[y];++m;F[x]=0;}
}
}
}
// build adjacency lists
for(i=0;N>i;++i){I[i]=0;}
for(i=0;m>i;++i){++I[E[i][0]];++I[E[i][1]];}
c=I[0];I[0]=0;for(i=1;N>=i;++i){a=I[i];I[i]=I[i-1]+c;c=a;}
for(i=0;N>i;++i){J[i]=I[i];}
for(i=0;m>i;++i){A[J[E[i][0]]++]=E[i][1];A[J[E[i][1]]++]=E[i][0];}
}
void print()
{ int i,x,t,y;
printf("Forest of biconnected components\n");
printf("%d component vertices, %d graph vertices\n",n,N-n);
printf("Component vertices:");for(i=0;n>i;++i){printf(" %d",V[i]);}printf("\n");
printf("Graph vertices:");for(i=n;N>i;++i){printf(" %d",V[i]);}printf("\n");
printf("Adjacency lists:\n");
for(x=0;N>x;++x)
{ printf("adj[%d]:",x);
i=I[x];t=I[x+1];while(i<t){y=A[i++];printf(" %d",y);}
printf("\n");
}
}
// tree component node contains graph node w?
bool contains(int c,int w)
{ int s,t,x,y;
s=biconnected::I[c];
t=biconnected::I[c+1];
while(s<t)
{ x=biconnected::C[s].x;
y=biconnected::C[s].y;
++s;
if(x==w){return true;}
if(y==w){return true;}
}
return false;
}
}
// For any 3 vertices x, y, and z in a biconnected component with 3 nodes or more
// there is a simple path from x to z through y.
// hamilton::process() searches for a hamiltonian path from node 0 to node Z
// node Z is what value Z contains if Z is positive, any node but 0 if Z is negative
namespace hamilton
{
int N;// number of vertices
int Z;// node Z
int A[maxc];// adjacency
signed char B[1<<maxc][maxc];// B[Y][x] - node before x on simple path from node 0 to node x through nodes Y
int Q[(1<<maxc)*maxc]; // queue s,x updates
void process()
{ int t,mdl,s,x,bx,y,by,qi,qo,sx;
t=(1<<N)-1;mdl=1+t;qi=qo=0;
/*
for(s=0;t>=s;++s)
{ for(x=0;N>x;++x)
{B[s][x]=-1;}
}
*/
memset(B,0xff,sizeof(B));
for(x=1;N>x;++x)
{ bx=(1<<x);
if(A[0]&bx)
{B[(1<<0)|bx][x]=0;Q[qi++]=((1<<0)|bx)+x*mdl;
}
}
while(qo<qi)
{ sx=Q[qo++];s=sx%mdl;x=sx/mdl;
for(y=1;N>y;++y)
{ by=(1<<y);
if((0==(s&by))&&(0!=(A[x]&by))&&(-1==B[s|by][y]))
{B[s|by][y]=x;Q[qi++]=(s|by)+y*mdl;}
}
}
}
int print_path(int*a)
{ int t,x,y,by,l,s,e,f,g;
t=(1<<N)-1;
for(y=1;N>y;++y)
{ if((-1!=B[t][y])&&((-1==Z)||(Z==y)))
{ l=0;s=t;
while(0!=y)
{ a[l++]=y;by=(1<<y);
x=B[s][y];s=s^by;y=x;
}
a[l++]=0;
// converse
e=0;f=l-1;
while(e<f)
{ g=a[e];a[e]=a[f];a[f]=g;
++e;--f;
}
return l;
}
}
return 0;
}
};
namespace problem
{
int S;// start point for spiridusi
int E;// santa's house (end point for spiridusi)
int Q;// start point for max
int P[2*maxn];// parent for dfs in forest
bool sol;// solution
int ans[maxn]; // the reunion of hamiltonian paths
int len; // the length of ans so far
int L1[maxn];// label 1
int L2[maxc];// label 2
void read_data()
{ freopen("santa.in","r",stdin);
int i;
scanf("%d %d",&(edges::N),&(edges::M));
for(i=0;edges::M>i;++i)
{ scanf("%d %d",&(edges::E[i].x),&(edges::E[i].y));
--edges::E[i].x;--edges::E[i].y;
}
scanf("%d %d %d",&S,&E,&Q);
--S;--E;--Q;
}
void build_hamilton_path_problem(int v,int c,int w)
{ // build labelings, compute node count
c=forest::V[c];
int i1=biconnected::I[c],i2=biconnected::I[c+1],i,t,x,y,f;
edge*C=biconnected::C;
i=i1;t=i2;
while(i<t)
{ x=C[i].x;y=C[i].y;++i;
L1[x]=L1[y]=-1;
}
f=0;
L1[v]=f;L2[f]=v;++f;//0
if(-1!=w)
{ L1[w]=f;L2[f]=w;++f;
w=1;
}
i=i1;t=i2;
while(i<t)
{ x=C[i].x;y=C[i].y;++i;
if(-1==L1[x]){L1[x]=f;L2[f]=x;++f;}
if(-1==L1[y]){L1[y]=f;L2[f]=y;++f;}
}
hamilton::N=f;
hamilton::Z=w;
// build adjacency
for(x=0;f>x;++x){hamilton::A[x]=0;}
i=i1;t=i2;
while(i<t)
{ x=L1[C[i].x];y=L1[C[i].y];++i;
hamilton::A[x]|=(1<<y);
hamilton::A[y]|=(1<<x);
}
}
void relabel_hamiltonian_path(int l1)
{ int i=len,t=len+l1;
while(i<t)
{ans[i]=L2[ans[i]];++i;}
len+=l1;
}
void DFS(int x)
{ int i=forest::I[x],t=forest::I[x+1],y;
while(i<t)
{ y=forest::A[i++];
if(-1==P[y])
{P[y]=x;DFS(y);}
}
}
// helpers
int find_s_node()
{ int c,t;
// Max moves from helpers to santa.
for(c=0;forest::n>c;++c)
{ if(forest::contains(c,S))
{ if(forest::contains(c,Q))
{ return c; }
}
}
// Max moves from santa to helpers.
// swap santa with helpers.
t=S;S=E;E=t;
for(c=0;forest::n>c;++c)
{ if(forest::contains(c,S))
{ if(forest::contains(c,Q))
{ return c; }
}
}
return -1;
}
// The first guess for where santa is.
int find_e_node_estimate()
{ int c;
for(c=0;forest::n>c;++c)
{ if(forest::contains(c,E))
{return c;}
}
return -1;
}
// The component where santa is.
int find_e_node(int s)
{ int e,x,o;
e=find_e_node_estimate();
if(-1==e)
{return -1;}
// Unique path in tree between.
for(x=0;forest::N>x;++x){P[x]=-1;}
P[e]=e;DFS(e);
// Not reachable.
if(-1==P[s])
{return -1;}
// Move closer.
o=s;
while(s!=e)
{ o=s;
s=P[s];//articulation
s=P[s];//2-component
}
if(forest::contains(forest::V[o],E))
{e=o;}
return e;
}
void print_dfs()
{ printf("DFS!\n");
int i;
for(i=0;forest::N>i;++i)
{printf("P[%d]=%d; ",i,P[i]);}
printf("\n");
}
//#define VERBOSE
void solve()
{ if((S==E)&&(Q==E))
{ ans[0]=S;len=1;
sol=true;
return;
}
edges::init();
biconnected::process();
forest::process();
#ifdef VERBOSE
biconnected::print_components();
biconnected::print_articulation_points();
forest::print();
#endif
sol=false;
int s,e,x,c,y,l;
s=find_s_node();
if(-1==s)
{return;}
e=find_e_node(s);
#ifdef VERBOSE
print_dfs();
#endif
if(-1==e)
{return;}
// Find hamiltonian paths.
if(Q==forest::V[P[s]])
{ len=1;ans[0]=Q;s=P[P[s]];// Move to entry in next component!
if((S!=Q)&&(s!=e))
{return;}
}
x=Q;c=s;len=0;
do
{ y=((c==e)?(-1):(forest::V[P[c]]));
build_hamilton_path_problem(x,c,y);
hamilton::process();
len=(0<len)?(len-1):0;//last equals first
l=hamilton::print_path(&ans[len]);
if(0==l)
{return;}
relabel_hamiltonian_path(l);
c=(c==e)?(-1):(P[P[c]]);x=y;
} while(-1!=c);
sol=true;
}
void write_data()
{ freopen("santa.out","w",stdout);
if(!sol)
{printf("No chance\n");return;}
printf("%d\n",len);
int i;printf("%d",1+ans[0]);
for(i=1;len>i;++i){printf(" %d",1+ans[i]);}
printf("\n");
}
}
int main()
{ problem::read_data();
problem::solve();
problem::write_data();
return 0;
}