#include <fstream>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <stack>
#include <vector>
using namespace std;
const int N = 45005;
const char fail[] = "impossibru\n";
vector<int> graph[N], G[2 * N], comp[N], sol;
int T[2 * N], depth[N], componenta[N], n, S, D, Q, nrComp, nrU;
bool critic[N], use[N], STOP;
stack<int> lista;
struct Muchie{
int x, y;
Muchie(){
x = y = 0;
}
Muchie(int _x, int _y){
x = _x;
y = _y;
}
};
stack<Muchie> St;
ifstream in("santa.in");
ofstream out("santa.out");
void add(Muchie M, int C){
int x = M.x, y = M.y;
comp[C].push_back(x);
comp[C].push_back(y);
if (componenta[x] && componenta[x] != C)
critic[x] = true;
if (componenta[y] && componenta[y] != C)
critic[y] = true;
componenta[x] = C;
componenta[y] = C;
}
void cbc(int x, int D, int T){
depth[x] = D;
St.push(Muchie(T, x));
for (vector<int> :: iterator it = graph[x].begin() ; it != graph[x].end() ; it++){
if (*it == T)
continue;
if (depth[*it]){
if (!St.empty() && depth[*it] <= depth[St.top().x])
++nrComp;
while (!St.empty() && depth[*it] <= depth[St.top().x]){
add(St.top(), nrComp);
St.pop();
}
continue;
}
cbc(*it, 1 + D, x);
}
if (!St.empty() && St.top().x && St.top().y == x){
add(St.top(), ++nrComp);
St.pop();
}
}
void cleanup(vector<int>& v){
sort(v.begin(), v.end());
int i, j;
for (i = 0, j = 0 ; i < v.size() ; i++)
if (v[i] != v[i - 1])
v[j++] = v[i];
v.resize(j);
}
void read(){
int m, x, y;
in >> n >> m;
while (m--){
in >> x >> y;
graph[x].push_back(y);
graph[y].push_back(x);
}
in >> S >> D >> Q;
}
void add_edge(int x, int y){
G[x].push_back(y);
G[y].push_back(x);
}
void arbore(){
for (int k = 1 ; k <= nrComp ; k++)
for (vector<int> :: iterator it = comp[k].begin() ; it != comp[k].end() ; it++)
if (critic[*it])
add_edge(N + k, *it);
}
void dfs(int x){
for (vector<int> :: iterator it = G[x].begin() ; it != G[x].end() ; it++)
if (!T[*it]){
T[*it] = x;
dfs(*it);
}
}
bool same_comp(int x, int y){
if (x == y)
return true;
for (int i = 1 ; i <= nrComp ; i++){
int nr = 0;
for (vector<int> :: iterator it = comp[i].begin() ; it != comp[i].end() ; it++)
if (*it == x || *it == y)
++nr;
if (nr > 1)
return true;
}
return false;
}
void sch(int& a, int& b){
int c = a;
a = b;
b = c;
}
void bkt(vector<int>& v, int x, int D){
if (STOP)
return;
--nrU;
sol.push_back(x);
use[x] = true;
if (x == D){
STOP = nrU == 0;
return;
}
if (D == -1 && !nrU){
STOP = true;
return;
}
for (vector<int> :: iterator it = graph[x].begin() ; it != graph[x].end() ; it++)
if (!use[*it]){
use[*it] = true;
bkt(v, *it, D);
}
if (!STOP)
sol.pop_back();
use[x] = false;
++nrU;
}
bool solvable(vector<int>& v, int S, int D){
memset(use, true, sizeof(use));
for (vector<int> :: iterator it = v.begin() ; it != v.end() ; it++)
use[*it] = false;
STOP = false;
nrU = v.size();
bkt(v, S, D);
return STOP;
}
bool solve(){
int S, D, C;
while (!lista.empty()){
S = lista.top(); lista.pop();
C = lista.top();lista.pop();
D = -1;
if (!lista.empty())
D = lista.top();
if (!solvable(comp[C - N], S, D))
return false;
}
return true;
}
int main(){
read();
//componente biconexe
cbc(S, 0, 0);
for (int i = 1 ; i <= nrComp ; i++)
cleanup(comp[i]);
/*
cout << nrComp << "\n";
for (int i = 1 ; i <= nrComp ; i++){
for (vector<int> :: iterator it = comp[i].begin() ; it != comp[i].end() ; it++)
cout << *it << " ";
cout << "\n";
}
for (int i = 1 ; i <= n ; i++)
cout << critic[i] << " ";
cout << "\n";
*/
arbore(); //construire arbore cbc
//determinare drum
if (!same_comp(S, Q) && !same_comp(D, Q)){
out << fail;
return 0;
}
if (!same_comp(S, Q))
sch(S, D);
S = critic[S] ? S : componenta[S] + N;
D = critic[D] ? D : componenta[D] + N;
T[S] = -1;
dfs(S);
if (D < N)
D = T[D];
for (int i = D ; i > 0 ; i = T[i])
lista.push(i);
if (lista.top() < N)
lista.pop();
lista.push(Q);
/*
while (!lista.empty()){
cout << lista.top() << " ";
lista.pop();
}
*/
if (!solve()){
out << fail << "\n";
return 0;
}
out << sol.size() << "\n";
for (vector<int> :: iterator it = sol.begin() ; it != sol.end() ; it++)
out << *it << " ";
out << "\n";
return 0;
}