#include <cstdio>
#include <vector>
#include <utility>
#include <stack>
#include <algorithm>
#include <bitset>
#include <queue>
#include <cstring>
typedef std::pair<int,int> Edge;
const int MAX_N(45005);
const int MAX_SIZE(17);
int n, m, s, e, q, Start, End;
std::vector<int> Graph [MAX_N];
std::vector<std::vector<int>> Components;
bool Flag [MAX_N];
int Level [MAX_N];
int Low [MAX_N];
bool Valid(true);
std::deque<int> Result;
std::stack<Edge> Stack;
std::bitset<MAX_N> Cs, Ce, Cq;
std::vector<int> InsideComponent [MAX_N];
std::vector<Edge> Tree [MAX_N];
int Pred [MAX_N];
int PredPoint [MAX_N];
std::vector<int> Path;
std::vector<int> Points;
int Dp [1 << MAX_SIZE] [MAX_SIZE];
int Index [MAX_N];
bool Mark [MAX_N];
inline void Read (void)
{
std::freopen("santa.in","r",stdin);
std::scanf("%d %d",&n,&m);
for (int i(1), a, b ; i <= m ; ++i)
{
std::scanf("%d %d",&a,&b);
Graph[a].push_back(b);
Graph[b].push_back(a);
}
std::scanf("%d %d %d",&s,&e,&q);
std::fclose(stdin);
}
inline void Print (void)
{
std::freopen("santa.out","w",stdout);
if (Valid)
{
std::printf("%d\n",static_cast<int>(Result.size()));
for (auto it : Result)
std::printf("%d ",it);
}
else
std::printf("No chance");
std::putchar('\n');
std::fclose(stdout);
}
void BiconnectedComponent (Edge x)
{
static std::bitset<MAX_N> Mark;
static std::vector<int> c;
Mark.reset();
c.clear();
while (Stack.top() != x)
{
Mark[Stack.top().first] = Mark[Stack.top().second] = true;
Stack.pop();
}
Mark[x.first] = Mark[x.second] = true;
Stack.pop();
for (int i(1) ; i <= n ; ++i)
if (Mark[i])
{
c.push_back(i);
InsideComponent[i].push_back(Components.size());
}
if (Mark[s])
Cs[Components.size()] = true;
if (Mark[e])
Ce[Components.size()] = true;
if (Mark[q])
Cq[Components.size()] = true;
Components.push_back(c);
}
void DepthFirstSearch (int node, int parent, int level)
{
Level[node] = Low[node] = level;
for (auto it : Graph[node])
if (it != parent)
{
if (Level[it])
Low[node] = std::min(Level[it],Low[node]);
else
{
Stack.push(std::make_pair(node,it));
DepthFirstSearch(it,node,level + 1);
Low[node] = std::min(Low[node],Low[it]);
if (Low[it] >= Level[node])
{
BiconnectedComponent(std::make_pair(node,it));
Flag[node] = true;
}
}
}
}
inline void Check (void)
{
if (s == e && q != s)
{
Valid = false;
return;
}
if (!(Cq[Start] || Cq[End]))
{
Valid = false;
return;
}
if (!Ce[s] && Cq[End] && Flag[e] && e != q)
{
Valid = false;
return;
}
if (!Ce[s] && Cq[Start] && Flag[s] && s != q)
Valid = false;
}
inline void Build (void)
{
for (int i(0) ; i < static_cast<int>(Components.size()) ; ++i)
for (auto node : Components[i])
if (Flag[node])
for (auto it : InsideComponent[node])
if (it != i)
Tree[i].push_back(std::make_pair(it,node));
}
inline void BreadthFirstSearch (void)
{
int node;
std::queue<int> Queue;
std::bitset<MAX_N> Mark;
for (auto it : InsideComponent[s])
{
Queue.push(it);
Pred[it] = it;
Mark[it] = true;
}
while (!Queue.empty())
{
node = Queue.front();
Queue.pop();
if (Ce[node])
{
End = node;
return;
}
for (auto it : Tree[node])
if (!Mark[it.first])
{
Mark[it.first] = true;
Pred[it.first] = node;
PredPoint[it.first] = it.second;
if (Ce[it.first])
{
End = it.first;
return;
}
Queue.push(it.first);
}
}
}
inline void RecoverPath (void)
{
int node(End);
while (Pred[node] != node)
{
Points.push_back(PredPoint[node]);
Path.push_back(node);
node = Pred[node];
}
Path.push_back(node);
Start = node;
std::reverse(Path.begin(),Path.end());
std::reverse(Points.begin(),Points.end());
}
inline int Bit (const int X)
{
return 1 << X;
}
inline bool Hamilton (int index, int start, int end = 0)
{
const int END(1 << Components[index].size());
std::memset(Dp,0,sizeof(Dp));
static std::vector<int> Path;
Path.clear();
int conf, i, node;
for (i = 0 ; i < static_cast<int>(Components[index].size()) ; ++i)
{
Index[Components[index][i]] = i;
Mark[Components[index][i]] = true;
}
conf = Bit(Index[start]);
Dp[conf][Index[start]] = -2;
for (conf = 1 ; conf < END ; ++conf)
for (i = 0 ; i < static_cast<int>(Components[index].size()) ; ++i)
if ((conf & Bit(i)) && Dp[conf][i])
for (auto it : Graph[Components[index][i]])
if (Mark[it] && !(Bit(Index[it]) & conf) && !Dp[conf | Bit(Index[it])][Index[it]])
Dp[conf | Bit(Index[it])][Index[it]] = (i ? i : -1);
bool ok(false);
if (!end)
for (auto it : Components[index])
{
if (Dp[END - 1][Index[it]])
{
node = Index[it];
if (node == -1)
node = 0;
conf = END - 1;
ok = true;
}
}
else if (Dp[END - 1][Index[end]])
{
node = Index[end];
if (node == -1)
node = 0;
conf = END - 1;
ok = true;
}
if (ok)
while (Dp[conf][node] != -2)
{
Path.push_back(node);
i = conf;
conf ^= Bit(node);
node = Dp[i][node];
if (node == -1)
node = 0;
}
for (i = 0 ; i < static_cast<int>(Components[index].size()) ; ++i)
Mark[Components[index][i]] = false;
std::reverse(Path.begin(),Path.end());
for (i = 0 ; i < static_cast<int>(Path.size()) ; ++i)
Result.push_back(Components[index][Path[i]]);
return ok;
}
inline void Dynamic (void)
{
if (Start == End)
{
Valid = Hamilton(Start,q);
Result.push_front(q);
return;
}
std::vector<int> v;
if (Cq[Start])
{
int node(q);
for (int i(0) ; i < static_cast<int>(Points.size()) ; ++i)
{
Valid = Hamilton(Path[i],node,Points[i]);
node = Points[i];
if (!Valid)
return;
}
Valid = Hamilton(End,Points.back());
}
else
{
int node(q);
for (int i(Points.size() - 1) ; i >= 0 ; --i)
{
Valid = Hamilton(Path[i + 1],node,Points[i]);
node = Points[i];
if (!Valid)
return;
}
Valid = Hamilton(Start,Points.front());
}
Result.push_front(q);
}
int main (void)
{
Read();
DepthFirstSearch(1,1,1);
Build();
BreadthFirstSearch();
RecoverPath();
Check();
if (Valid)
Dynamic();
Print();
return 0;
}