#include <bits/stdc++.h>
#define REP(i,n) for (long long i=0;i<(n);i++)
#define FOR(i,a,b) for (long long i=(a);i<(b);i++)
#define dump(x)  cerr << #x << " => " << (x) << endl
#define MIN(vec) *min_element(vec.begin(), vec.end())
#define MAX(vec) *max_element(vec.begin(), vec.end())
#define UNIQ(vec) vec.erase(unique(vec.begin(), vec.end()),vec.end()) //ソートの必要あり
#define IN(n,m)  (!(m.find(n) == m.end()))
#define FINDL(vec,x) (lower_bound(vec.begin(),vec.end(),x) - vec.begin())
#define FINDU(vec,x) (upper_bound(vec.begin(),vec.end(),x) - vec.begin())
#define EQ(a,b) (abs(a - b) < 1e-10)
using namespace std;
typedef long long LL;
constexpr int dx[4] = {0,1,0,-1};
constexpr int dy[4] = {1,0,-1,0};
constexpr long double pi = M_PI;
constexpr double eps = 1e-10;
constexpr long mod = 1000000007;
// LONG_MAX,LLONG_MAX
template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P)
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, vector<T> P)
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, vector<vector<T> > P)
{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }
template<class Key,class Value> ostream& operator << (ostream &s, map<Key,Value> M)
{ for ( auto itr = begin(M); itr != end(M); ++itr) { s << itr->first << ":" << itr->second; } return s;}

using Long = long long;

template<typename W>
struct Edge { 
    int to,rev;
    W cap;
    Edge(int to, int rev, W cap) : to(to), rev(rev), cap(cap) {}
};

template<typename W>
using Graph = vector<vector<Edge<W>>>;

template<typename W>
struct NetWork {
    Graph<W> G;
    NetWork(int V) : G(V) { }
    void add_edge(int from, int to, W cap) {
        G[from].emplace_back(to, (int)G[to].size(), cap);
        G[to].emplace_back(from, (int)G[from].size()-1, 0);
    }
};

// private
template<typename W>
void bfs(int s, Graph<W> &g, vector<int> &level) {
    fill(level.begin(),level.end(), -1);
    queue<int> que;
    level[s] = 0;
    que.push(s);
    while(!que.empty()) {
        int v=que.front();que.pop();
        for(auto &&e : g[v]) {
            if( e.cap > 0 && level[e.to] < 0) {
                level[e.to] = level[v]+1;
                que.push(e.to);
            }
        }
    }
}

// private
template<typename W>
W dfs(int v,int t,W f, Graph<W> &g, vector<int> &iter, vector<int> &level) {
    if(v==t) return f;
    for(int &i = iter[v] ; i < g[v].size();i++ ) {
        Edge<W> &e = g[v][i];
        if( e.cap > 0 && level[v]<level[e.to] ) {
            int d = dfs(e.to, t , min(f , e.cap), g, iter, level);
            if( d > 0 ) {
                e.cap-=d;
                g[e.to][e.rev].cap += d;
                return d;
            }
        }
    }
    return 0;
}

// Dinic法
template<typename W>
W max_flow(NetWork<W> &network, int s, int t) {
    W flow = 0;
    // networkのグラフ
    Graph<W> &g = network.G;
    // level[i] : 頂点sから頂点iまでの最短距離
    vector<int> level(g.size(), -1);
    vector<int> iter(g.size(), 0);
    for( ; ; ) {
        bfs(s, g, level);
        // フローを流せるエッジが存在しない.
        if( level[t] < 0 ) return flow;
        fill(iter.begin(),iter.end(),0);
        int f;
        while( (f=dfs(s , t, numeric_limits<W>::max(), g, iter, level)) > 0){
            flow += f;
        }
    }
    return flow;
}

int main(void) {
	cin.tie(0);
	ios::sync_with_stdio(false);

    int N, M, S, T, U, V;
    cin >> N >> M >> S >> T >> U >> V;
    S--;T--;U--;V--;
    NetWork<int> network1(N+2);
    NetWork<int> network2(N+2);
    REP(i, M) {
        int u,v;
        cin >> u >> v;
        u--;v--;
        network1.add_edge(u, v, 1);
        network1.add_edge(v, u, 1);
        network2.add_edge(u, v, 1);
        network2.add_edge(v, u, 1);
    }
    int SS = N;
    int GG = N+1;
    network1.add_edge(SS, S, INT_MAX / 2);
    network1.add_edge(T, GG, INT_MAX / 2);
    network1.add_edge(SS, U, INT_MAX / 2);
    network1.add_edge(V, GG, INT_MAX / 2);

    network2.add_edge(SS, S, INT_MAX / 2);
    network2.add_edge(T, GG, INT_MAX / 2);
    network2.add_edge(SS, V, INT_MAX / 2);
    network2.add_edge(U, GG, INT_MAX / 2);

    cout << min( max_flow(network1, SS, GG), max_flow(network2, SS, GG)) << endl;
    

}




Measured memory_bytes: 19240