#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <queue>
#include <ctime>
using namespace std;
#define file "santa"
#define NM 41000
#define KM 16
#define FOR(i,s,e) for(int i = (int) s; i< (int) e; ++i)
#define REP(i,n) FOR(i,0,n)
#define pb push_back
#define size(x) (int) (x.size())
#define tip(x) cout << #x << " = " << x<< endl
vector<int> m[NM];
vector<int> comp[NM];
vector<int> backc[NM];
bool cp[NM];
int c[NM], ck, curcomp;
int N, S, E, Q, sol1, sol2;
#define SM (1<<KM)
int d[SM][KM], sol[NM], sk=0;
int mk[NM], mkid=2;
int way[NM], wk; // asta va tine minte punctele de frontiera pana de la S la E generat cu get_way
int ids[KM], k, tids[NM];
int lev[NM], up[NM];
void read_data();
void getFrontier(int x=0, int f=-1);
void df(int Q);
void hamWay(); //start is always ids[0]
void buffer_way(int s, int n);
void get_way();
void split(int x=0, int f=-1, int cc=0);
bool prepare(int x, int y); // this shuld prepare ids and k s.t. x in ids[0], y is ids[1] and the rest is the component where both x and y belong to
int main() {
freopen(file".in","rt",stdin);
freopen(file".out","wt",stdout);
read_data();
getFrontier(); if (c[0]!=1) cp[0]=true;
memset(mk, 0, sizeof(mk));
if (!cp[0]) comp[0].pb(0);
split();
// REP(i,N) if (cp[i]) printf("%d ", i+1); printf("\n");
FILE *DEBUG;
DEBUG = fopen("santa.debug", "wt");
REP(i, ck) {
fprintf(DEBUG,"%d\n", size(comp[i]));
/* REP(j, size(comp[i]) ) {
printf("%d ", comp[i][j]+1);
}
printf("\n");*/
}
fclose(DEBUG);
//Build the node->component matrix
REP(i, ck)
REP(j, size(comp[i]) )
backc[comp[i][j]].pb(i);
memset(mk, 0, sizeof(mk));
//Good so far
df(Q); // marcheaza punctele din zona curenta cu ++mkid (autoincrementat)
curcomp=backc[Q][0];
if ( !mk[S] && !mk[E] ) //I'm not at either start or end
{
printf("No chance\n");
fclose(stdout);
return 0;
}
if ( mk[S] && mk[E] ) // S & E are in the same component with me so just get a ham way and print it
{
hamWay();
REP(i,k)
if ( d[(1<<k)-1][i] != -1)
buffer_way((1<<k)-1,i);
} else {
if ( mk[E] ) { // inseamna ca sunt in E si vreau sa ajung in S, deci swap ca sa ajung in starea normala...
int t=E; E=S; S=t;
}
get_way();
way[0]=Q;
REP(i, wk-1)
{
// cout << way[i]+1 << " ";
memset(tids,0xff,sizeof(tids));
if (! prepare(way[i], way[i+1]) ){
printf("NO\npreparefailed");
fclose(stdout);
return 0;
}
hamWay();
if ( d[(1<<k)-1][1] == -1) {
printf("NO\nimposible way");
for(int i=0; i<k; i++)
{
printf("%d : ", ids[i]);
for(int j=0; j<size(m [ids[i]]); ++j)
if (tids[ m[ids[i]][j] ]!=-1)
printf("%d ", m[ids[i]][j]);
printf("\n");
}
fclose(stdout);
return 0;
}
buffer_way((1<<k)-1, 1);
sk--; // Not to repeate frontier nodes it will be added again by the next component
}
sol[sk++]=E;
//cout << endl;
}
printf("%d\n", sk);
REP(i, sk)
printf("%d ", sol[i]+1);
fclose(stdout);
return 0;
}
int getCommonComponent(int x, int y)
{
REP(i, size(backc[x]))
REP(j, size(backc[y]))
if (backc[x][i] == backc[y][j]) return backc[x][i];
return -1;
}
bool prepare(int x, int y) // this shuld prepare ids and k s.t. x in ids[0], y is ids[1] and the rest is the component where both x and y belong to
{
int w=getCommonComponent(x,y);
if (w==-1) return false;
curcomp=w;
k=0;
++k;
ids[k-1]=x;
++k;
ids[k-1]=y;
tids[x]=0; tids[y]=1;
REP(i, size(comp[w]) )
if ( (comp[w][i] != x) && (comp[w][i] != y) )
tids[comp[w][i]]=k, ids[k++]=comp[w][i];
return true;
}
void split(int x, int f, int cc) {
mk[x]=1;
REP ( i,size(m[x]))
if ( m[x][i]!=f ) {
if ( ! mk[ m[x][i] ] ) {
if (cp[x] && (up[ m[x][i] ]>=lev[x])) {
comp[ck].pb(x);
comp[ck].pb(m[x][i]);
ck++;
split(m[x][i], x, ck-1);
} else {
comp[cc].pb(m[x][i]);
split( m[x][i], x, cc);
}
}
}
}
void get_way() {
bool mk[NM]; memset(mk,0, sizeof(mk));
int f[NM];
int q[NM], s,e;
s=0;
e=1;
f[S]=-1;
q[0]=S;mk[S] = true;
while (s<e){
REP(i, size(m[q[s]]) )
if (!mk[ m[q[s]][i] ]){
q[e++]=m[q[s]][i];
mk[q[e-1]] = true;
f[ q[e-1]] = q[s];
}
s++;
}
//REP(i,e) cout << q[i]+1<<","<< f[q[i]]+1 << " "; cout << endl;
e=2;s=f[E];
while (s!=S) {
if ( cp[s] ) ++e;
s=f[s];
}
s=f[E];wk=e;
way[--e]=E;
while (s!=S) {
if ( cp[s] ) way[--e]=s;
s=f[s];
}
way[--e]=S;
}
void buffer_way(int s, int n) {
if ( d[s][n] )
buffer_way( d[s][n]/KM, d[s][n]%KM );
sol[sk++]= ids[n];
}
void hamWay() {
memset(d, 0xff, sizeof(d));
d[1][0] = 0; queue<int> w;
w.push(1*KM + 0);
while (! w.empty() )
{
int state = w.front() /KM;
int nod = w.front() % KM;
REP(i, size(m[ids[nod]]))
{
if ( (tids[ m[ ids[nod] ][i] ]!=-1) && ( ! (state & (1<<tids[ m[ ids[nod] ][i] ])==0)) &&
d[state | (1<<tids[ m[ ids[nod] ][i] ])][ tids[ m[ ids[nod] ][i] ] ]==-1 ) {
d[state | (1<<tids[ m[ ids[nod] ][i] ])][ tids[ m[ ids[nod] ][i] ] ]= w.front();
w.push( (state | (1<<tids[ m[ ids[nod] ][i] ]))*KM + tids[ m[ ids[nod] ][i] ] );
}
}
w.pop();
}
}
void df(int Q) {
mkid++;
k = 1; ids[0] = Q; tids[Q] = 0;
queue<int> w;
w.push(Q);
mk[Q] = mkid;
while ( ! w.empty() )
{
int c = w.front(); w.pop();
if ( ! cp[c] )
REP ( i, size(m[c]))
if ( mk[ m[c][i] ] == 0 )
{
mk[ m[c][i] ] = mkid;
w.push(m[c][i]);
tids[m[c][i]]=k;
ids[k++] = m[c][i];
}
}
}
void getFrontier(int x, int f) {
up[x] = lev[x];
mk[x] = true;
c[x] = 0;
cp[x] = false;
REP ( i,size(m[x]))
if (m[x][i]!=f) {
if ( ! mk[ m[x][i] ] ) {
c[x]++;
lev[ m[x][i] ] = lev[x] +1;
getFrontier( m[x][i], x);
if ( ! ( up[ m[x][i] ] < lev[x] )) cp[x] = true;
if ( up[ m[x][i] ] < up[x] ) up[x] = up[m[x][i]];
} else if ( (m[x][i] != f) && (lev[ m[x][i] ] < up[x]) )
up[x] = lev[ m[x][i] ];
}
}
void read_data() {
int M,x,y;
scanf("%d%d", &N, &M);
REP(i,M) {
scanf("%d%d", &x, &y);x--,y--;
m[x].pb(y);
m[y].pb(x);
}
scanf("%d%d%d", &S, &E, &Q);
S--,E--,Q--;
}