#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
#define MAXN 45005
int N, M;
int S, D, Qs;
vector<int> con[MAXN];
int alt[MAXN], p[MAXN], low[MAXN], art[MAXN], u[MAXN];
vector<int> nodincomp[MAXN];
vector< vector<int> > compnod;
vector< vector< pair<int, int> > > compmuc;
vector<bool> usecomp, usenod;
vector< pair<int, int> > st;
/*
* introduce muchia (a, b) in stiva
*/
void push(int a, int b) { st.push_back( make_pair(a, b) ); }
/*
* extrage componenta biconexa
* scoate muchii din stiva pana ajunge la (a, b)
*/
void popcomp(int a, int b)
{
vector<int> noduri;
vector< pair<int, int> > muchii;
noduri.clear(); muchii.clear();
for (; 1; st.pop_back())
{
noduri.push_back( st.back().first );
noduri.push_back( st.back().second );
muchii.push_back( st.back() );
if ( st.back() == make_pair(a, b) )
{
st.pop_back();
break;
}
}
sort(noduri.begin(), noduri.end());
sort(muchii.begin(), muchii.end());
noduri.resize( unique(noduri.begin(), noduri.end()) - noduri.begin() );
muchii.resize( unique(muchii.begin(), muchii.end()) - muchii.begin() );
compnod.push_back( noduri );
compmuc.push_back( muchii );
usecomp.push_back( false ); //aflu mai tarziu daca componenta respectiva e pe drumu piticilor :)
//drumul piticilor va fi un sir de componente biconexe si puncte de articulatie
//fiecare punct de articulatie va aparea doar o data in drum si astfel se va trece
//prin maxim 2 componente biconexe legate de orice punct de articulatie
for (size_t i = 0; i < noduri.size(); i++)
nodincomp[ noduri[i] ].push_back( (int)compnod.size() - 1 );
}
/*
* afla componentele biconexe
*/
void dfs(int k)
{
int NCHILD = 0; //numarul de fii in arborele DF al nodului curent, util sa vad daca nodu 1 e critic
u[k] = 1;
low[k] = alt[k];
vector<int> :: iterator it;
for (it = con[k].begin(); it != con[k].end(); it++)
{
if (!u[*it])
{
alt[*it] = alt[k] + 1;
p[*it] = k;
push(k, *it);
dfs(*it);
NCHILD++;
if (low[*it] < low[k])
low[k] = low[*it];
if (low[*it] >= alt[k]) //nodul k e critic
{
art[k] = 1;
if (k == 1 && NCHILD < 2)
art[k] = 0;
popcomp(k, *it); //extrage componenta biconexa
}
}
else
if (*it != p[k] && alt[*it] < alt[k])
{
push(k, *it);
if (alt[*it] < low[k])
low[k] = alt[*it];
}
}
}
/*
* marcheaza componenta biconexa (cur) ca facand parte dintr-un potential drum al piticilor
*/
inline void MARK(int cur)
{
vector< int > :: iterator it;
usecomp[cur] = true;
for (it = compnod[cur].begin(); it != compnod[cur].end(); it++)
usenod[*it] = true;
}
/*
* marcheaza nodurile ce trebuie vizitate
*/
queue<int> Q;
int START, END; //prima si ultima componenta biconexa din drumul piticilor
vector< bool > hasS, hasD, hasQs;
int bfs(int S)
{
for (; !Q.empty(); Q.pop());
int i;
vector< int > :: iterator it;
memset(u, -1, sizeof(u));
usenod.clear(); usenod.resize(N + 1, false);
hasS.resize( compnod.size(), false );
hasD.resize( compnod.size(), false );
hasQs.resize( compnod.size(), false );
for (size_t k = 0; k < compnod.size(); k++)
for (size_t a = 0; a < compnod[k].size(); a++)
{
if (compnod[k][a] == S) hasS[k] = true;
if (compnod[k][a] == D) hasD[k] = true;
if (compnod[k][a] == Qs) hasQs[k] = true;
}
START = -1;
for (size_t k = 0; k < compnod.size(); k++)
if ((hasS[k] && hasQs[k]) || (hasD[k] && hasQs[k]))
{
START = k;
break;
}
if (START == -1)
return 0;
int foundS, foundD;
foundS = hasS[START] ? 1 : 0;
foundD = hasD[START] ? 1 : 0;
if (foundS && foundD)
{
END = START;
MARK(START);
return 1;
}
for (Q.push(START), u[START] = START; !Q.empty() && (!foundS || !foundD); Q.pop())
{
i = Q.front();
for (size_t k = 0; k < compnod[i].size(); k++)
{
int n = compnod[i][k];
for (it = nodincomp[n].begin(); it != nodincomp[n].end(); it++)
{
if (u[*it] != -1)
continue;
u[*it] = i;
Q.push( *it );
if (!foundD && hasD[*it])
{
END = *it;
foundD = 1;
break;
}
if (!foundS && hasS[*it])
{
END = *it;
foundS = 1;
break;
}
}
}
}
if (!foundS || !foundD)
return 0;
for (i = END; i != START; i = u[i])
MARK(i);
MARK(START);
return 1;
}
int main()
{
freopen("santa.in", "rt", stdin);
freopen("santa.out", "wt", stdout);
scanf("%d %d", &N, &M);
for (; M; M--)
{
int i, j;
scanf("%d %d", &i, &j);
con[i].push_back(j);
con[j].push_back(i);
}
scanf("%d %d %d", &S, &D, &Qs);
dfs(1); //afla componentele biconexe
/* for (int i = 1; i <= N; i++)
if (art[i])
printf("%d ", i);
printf("\n");
for (size_t i = 0; i < compnod.size(); i++)
{
for (size_t j = 0; j < compnod[i].size(); j++)
printf("%d ", compnod[i][j]);
printf("\n");
for (size_t j = 0; j < compmuc[i].size(); j++)
printf("%d %d; ", compmuc[i][j].first, compmuc[i][j].second);
printf("\n\n");
}*/
if (!bfs(S)) //afla toate nodurile care trebuie atinse
{
printf("No chance\n");
return 0;
}
int NR = 0;
for (int i = 1; i <= N; i++)
if (usenod[i])
{
// printf("%d ", i);
NR++;
}
// printf("\n");
printf("%d\n", NR);
return 0;
}