#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define trav(a, x) for(auto& a : x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

template <class T>
struct Point {
    typedef Point P;
    T x, y;
    explicit Point(T x=0, T y=0) : x(x), y(y) {}
    bool operator<(P p) const { return tie(x,y) < tie(p.x,p.y); }
    bool operator==(P p) const { return tie(x,y)==tie(p.x,p.y); }
    P operator+(P p) const { return P(x+p.x, y+p.y); }
    P operator-(P p) const { return P(x-p.x, y-p.y); }
    P operator*(T d) const { return P(x*d, y*d); }
    P operator/(T d) const { return P(x/d, y/d); }
    T dot(P p) const { return x*p.x + y*p.y; }
    T cross(P p) const { return x*p.y - y*p.x; }
    T cross(P a, P b) const { return (a-*this).cross(b-*this); }
    T dist2() const { return x*x + y*y; }
    double dist() const { return sqrt((double)dist2()); }
    // angle to x-axis in interval [-pi, pi]
    double angle() const { return atan2(y, x); }
    P unit() const { return *this/dist(); } // makes dist()=1
    P perp() const { return P(-y, x); } // rotates +90 degrees
    P normal() const { return perp().unit(); }
    // returns point rotated 'a' radians ccw around the origin
    P rotate(double a) const {
        return P(x*cos(a)-y*sin(a),x*sin(a)+y*cos(a)); }
};

typedef Point<ll> P;
pair<vi, vi> ulHull(const vector<P>& S) {
    vi Q(sz(S)), U, L;
    iota(all(Q), 0);
    sort(all(Q), [&S](int a, int b){ return S[a] < S[b]; });
    trav(it, Q) {
#define ADDP(C, cmp) while (sz(C) > 1 && S[C[sz(C)-2]].cross(\
    S[it], S[C.back()]) cmp 0) C.pop_back(); C.push_back(it);
        ADDP(U, <=); ADDP(L, >=);
    }
    return {U, L};
}

vi convexHull(const vector<P>& S) {
    vi u, l; tie(u, l) = ulHull(S);
    if (sz(S) <= 1) return u;
    if (S[u[0]] == S[u[1]]) return {0};
    l.insert(l.end(), u.rbegin()+1, u.rend()-1);
    return l;
}

pair<LL,LL> neg(pair<LL,LL> d){
    return make_pair(-d.first, -d.second);
}

typedef Point<LL> P;
int main(){
    LL n;
    cin >> n;
    pair<LL,LL> a[n];
    pair<LL,LL> sum = make_pair(0,0);
    for(int i = 0; i < n; i++){
        cin >> a[i].first >> a[i].second;
        sum.first += a[i].first;
        sum.second += a[i].second;
        a[i].first *= n;
        a[i].second *= n;
    }
    map<pair<LL,LL>, LL> g;
    for(int i = 0; i < n; i++){
        a[i].first -= sum.first;
        a[i].second -= sum.second;
        g[a[i]]++;
        //cout << a[i].first << " " << a[i].second << endl;
    }
    for(int i = 0; i < n; i++){
        if(g[a[i]] > 0 && g[neg(a[i])] > 0){
            g.erase(a[i]);
            g.erase(neg(a[i]));
        }
    }
    g.erase(make_pair(0,0));
    vector<pair<LL,LL> > pts;
    for(map<pair<LL,LL>, LL>::iterator it = g.begin(); it != g.end(); it++){
        if(it->second <= 0) continue;
        pts.push_back(it->first);
    }
    if(pts.size() == 0){
        cout << -1 << endl;
        return 0;
    }
    vector<P> z;
    for(int i = 0; i < pts.size(); i++){
        z.push_back(P(pts[i].first, pts[i].second));
        //cout << z[i].x << " " << z[i].y << endl;
    }

    vector<int> hull = convexHull(z);

    vector<P> checks;
    for(int j = 0; j < hull.size(); j++){
        int nj = (j+1) % (hull.size());
        P diff = z[hull[nj]] - z[hull[j]];
        LL maxcross = 0;
        LL mincross = 0;
        for(int c = 0; c < z.size(); c++){
            maxcross = max(maxcross, diff.cross(z[c]));
            mincross = min(mincross, diff.cross(z[c]));
        }
        vector<int> maxs;
        vector<int> mins;
        for(int c = 0; c < hull.size(); c++){
            if(diff.cross(z[hull[c]]) == maxcross) maxs.push_back(hull[c]);
            if(diff.cross(z[hull[c]]) == mincross) mins.push_back(hull[c]);
        }
        for(int b = 0; b < maxs.size(); b++){
            for(int a = 0; a < mins.size(); a++){
                if(maxs[b] == mins[a]) continue;
                P del = z[maxs[b]] + z[mins[a]];
                LL gg = __gcd(del.x, del.y);
                del.x /= gg; del.y /= gg;
                if(del.x < 0 || (del.x == 0 && del.y < 0)){
                    del.x *= -1;
                    del.y *= -1;
                }
                checks.push_back(del);
            }
        }
    }
    map<pair<LL,LL>, int> fans;
    for(int j = 0; j < checks.size(); j++){
        map<LL,int> freq;
        for(int i = 0; i < z.size(); i++){
            freq[z[i].cross(checks[j])]++;
        }
        LL ok = 1;
        for(int i = 0; i < z.size(); i++){
            LL cur = z[i].cross(checks[j]);
            if(freq[cur] != freq[-cur]) ok = 0;
        }
        if(ok){
            fans[make_pair(checks[j].x, checks[j].y) ] = 1;
        }
    }
    cout << fans.size() << endl;
}


#include<bits/stdc++.h>
using namespace std;

typedef double lf;
typedef pair<int, int> pii;
typedef pair<lf, lf> pdd;

const int MN = 2010;

int N;
pii P[MN];
pdd C;
vector<pii> tmp;
int chk[MN];

struct Line {
    lf a, b, c;
    lf f(lf x, lf y) {
        return a * x + b * y + c;
    }
};

Line getLine(pdd p, pdd q) {
    return { (q.second - p.second), (p.first - q.first), (q.first - p.first) * p.second - (q.second - p.second) * p.first };
}

vector<lf> slope;

int main() {
    scanf("%d", &N);

    lf xsum = 0;
    lf ysum = 0;
    for(int i = 0; i < N; i++) {
        scanf("%d %d", &P[i].first, &P[i].second);
        xsum += P[i].first;
        ysum += P[i].second;
    }

    C = { xsum / N, ysum / N };

    for(int i = 0; i < N; i++) {
        for(int j = i; j < N; j++) {
            if(abs(2 * C.first - P[i].first - P[j].first) < 1e-9 && abs(2 * C.second - P[i].second - P[j].second) < 1e-9) {
                chk[i] = 1;
                chk[j] = 1;
                break;
            }
        }
    }

    for(int i = 0; i < N; i++) if(!chk[i]) tmp.push_back(P[i]);
    N = tmp.size();
    for(int i = 0; i < N; i++) P[i] = tmp[i];
    if(!N) {
        printf("-1");
        return 0;
    }

    for(int i = (N % 2? 0 : 1); i < N; i++) {
        pdd M = { (lf)(P[0].first + P[i].first) / 2, (lf)(P[0].second + P[i].second) / 2 };
        Line line = getLine(C, M);

        vector<lf> tmp;
        for(int j = 0; j < N; j++) {
            tmp.push_back(line.f(P[j].first, P[j].second));
        }
        sort(tmp.begin(), tmp.end());

        bool ok = true;
        for(int j = 0; j < N; j++) if(abs(tmp[j] + tmp[N - 1 - j]) > 1e-9) {
            ok = false;
            break;
        }
        if(ok) {
            if(line.a == 0) slope.push_back(1e9);
            else slope.push_back(line.b / line.a);
        }
    }

    sort(slope.begin(), slope.end());
    int ans = 0;
    for(int i = 0; i < slope.size(); i++) {
        if(i == 0 || abs(slope[i] - slope[i - 1]) > 1e-9) ans++;
    }

    printf("%d", ans);
}


#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <map>
#include <set>

using namespace std;

using ll = long long;
#define range(i,a,b) for(auto i=(a);i<(b);i++)
#define rep(i,n) range(i,0,n)
#define fst first
#define snd second

template <typename T>
struct Point {
T x, y;
inline Point & operator+=(const Point & o) { x += o.x, y += o.y; return *this; }
inline Point operator+(const Point & o) const { auto p = *this; return p += o; }
inline Point & operator-=(const Point & o) { x -= o.x, y -= o.y; return *this; }
inline Point operator-(const Point & o) const { auto p = *this; return p -= o; }
inline T operator*(const Point & o) { return x * o.x + y * o.y; }
inline T operator%(const Point & o) const { return x * o.y - y * o.x; }
inline bool operator==(const Point & o) const { return x == o.x && y == o.y; }
inline bool operator<(const Point & o) const { return x < o.x || (x == o.x && y < o.y); }
inline double r() const { return hypot(x, y); }
inline T q() const { return atan2(y, x); }
};
template <typename T> inline Point<T> operator*(T c, Point<T> a) { return {c * a.x, c * a.y}; }
template <typename T> inline Point<T> operator-(Point<T> a) { return (T) -1 * a; }

constexpr int N = 2005;

Point<ll> pts[N];

bool symmetric(Point<ll> * p0, Point<ll> * p1, Point<ll> & l) {
	map<ll, int> proj;
	range (pt, p0, p1) {
		ll d = *pt % l;
		if (d > 0) proj[d]++;
		else if (d < 0) proj[-d]--;
	}
	for (auto & p : proj) if (p.snd) return false;
	return true;
}

int work() {
	int n;
	scanf("%d", &n);

	Point<ll> ctr {0, 0};
	rep (i, n) {
		scanf("%lld%lld", &pts[i].x, &pts[i].y);
		ctr += pts[i];
	}

	set<Point<ll>> mirror;
	rep (i, n) {
		pts[i] = (ll) n * pts[i] - ctr;
		if (!mirror.erase(-pts[i])) mirror.insert(pts[i]);
	}

	n = 0;
	for (auto & pt : mirror) pts[n++] = pt;
	if (n < 2) return -1;

	int ans = 0;
	set<Point<ll>> ls;
	rep (i, n) {
		Point<ll> l = pts[0] + pts[i];
		ll g = __gcd(abs(l.x), abs(l.y)) * (Point<ll>{0, 0} < l ? 1 : -1);
		l.x /= g, l.y /= g;
		if (ls.count(l)) continue;
		ls.insert(l);
		ans += symmetric(pts, pts + n, l);
	}
	return ans;
}

int main() {
	printf("%d\n", work());
	return 0;
}


#include <iostream>
#include <vector>
#include <cmath>
#include <map>
#include <algorithm>
#include <cassert>
#define MAXN 2005
#define eps 1e-8
using namespace std;

const double PI = acos(-1);

struct Point {
    double x, y;

    Point(): x(0), y(0) {}
    Point(double x, double y): x(x), y(y) {}

    friend Point operator+(const Point &A, const Point &B);
    friend Point operator/(const Point &A, double k);
};

Point operator+(const Point &A, const Point &B) {
    return Point(A.x + B.x, A.y + B.y);
}

Point operator/(const Point &A, double k) {
    return Point(A.x / k, A.y / k);
}

int n;
Point p[MAXN], mass;
bool erased[MAXN];
vector<Point> vp;

bool equal(double x, double y) {
    return fabs(x - y) < eps;
}

struct Comp {
    bool operator()(double a, double b) {
        if (equal(a, b))
            return 0;
        return a < b;
    }
};

map<double, int, Comp> posLines;

Point getVector(const Point &A, const Point &B) {
    Point v(A.x - B.x, A.y - B.y);

    if (v.y < 0)
        v.x = -v.x, v.y = -v.y;

    return v;
}

Point getPerpendicularVector(const Point &v) {
    Point pv(-v.y, v.x);

    if (pv.y < 0)
        pv.x = -pv.x, pv.y = -pv.y;

    return pv;
}

Point rotate(const Point &P, double alfa) {
    double c = cos(alfa);
    double s = sin(alfa);

    return Point(c * P.x + s * P.y, -s * P.x + c * P.y);
}

bool check(double alfa) {
    vector<double> v;

    for (auto &P: vp)
        v.push_back(rotate(P, alfa).x);

    double massx = rotate(mass, alfa).x;

    sort(v.begin(), v.end());
    for (int i = 0, j = n - 1; i <= j; ++i, --j) {
        if (!equal(massx, (v[i] + v[j]) / 2))
            return 0;
    }

    return 1;
}

int main() {
    ios::sync_with_stdio(0);

    cin >> n;

    for (int i = 1; i <= n; ++i) {
        cin >> p[i].x >> p[i].y;
        mass = mass + p[i];
    }

    mass = mass / n;

    for (int i = 1; i <= n; ++i) {
        if (equal(p[i].x, mass.x) && equal(p[i].y, mass.y))
            erased[i] = 1;
        if (erased[i])
            continue;
        for (int j = i + 1; j <= n; ++j) {
            Point M = (p[i] + p[j]) / 2;

            if (equal(M.x, mass.x) && equal(M.y, mass.y))
                erased[i] = erased[j] = 1;
        }
    }

    for (int i = 1; i <= n; ++i) {
        if (!erased[i]) {
            vp.push_back(p[i]);
        }
    }

    if (vp.empty()) {
        cout << "-1\n";
        return 0;
    }

    n = (int) vp.size();

    for (int i = 0; i < n; ++i) {
        for (int j = i + 1; j < n; ++j) {
            Point M = (vp[i] + vp[j]) / 2;
            Point v = getPerpendicularVector(getVector(mass, M));

            double alfa = atan2(v.y, v.x);
            assert(alfa < -PI + eps || (alfa > -eps && alfa < PI + eps));
            if (alfa < -PI + eps)
                alfa = PI;

            ++posLines[alfa];
        }
    }

    int ans = 0;
    for (auto &entry: posLines) {
        if (entry.second >= n / 2) {
            ans += check(entry.first);
        }
    }

    cout << ans << "\n";

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn = 105;
typedef long long ll;

ll f[maxn >> 1];
ll cal(char c, int num) {
//	printf("%c %d\n", c, num);
	if(c == 'A') return (num & 1) ? f[(num >> 1) + 1] : f[(num >> 1) - 1];
	else return (num & 1) ? f[(num >> 1) + 1] : f[(num >> 1) + 2];
}
int main() {
	ios::sync_with_stdio(false); cin.tie(0);
	f[0] = 0, f[1] = 1;
	for(int i = 2; i < (maxn >> 1); i++) f[i] = f[i - 1] + f[i - 2];
	string s;
	cin >> s;
	int n = s.length();
	vector<int> v;
	for(int i = 0; i < n; i++)
		if(s[i] == s[(i - 1 + n) % n]) v.push_back(i);
	if(v.empty()) return 0 * printf("%lld\n", f[(n >> 1) - 1] + f[(n >> 1) + 1]);
	ll ans = 1;
	v.push_back(v[0] + n);
	int sz = (int)v.size();
	for(int i = 0; i < sz - 1; i++) ans *= cal(s[v[i]], v[i + 1] - v[i]);
	printf("%lld\n", ans);
	return 0;
}


#include <iostream>
#include <vector>
#define int long long
#define endl '\n'

using namespace std;

int a1[1000000+5];
vector <vector <int> > g;
bool used[1000000+5];
int timer, tin[1000000+5], fup[1000000+5];

vector <int> ans;

void dfs (int v, int p = -1) {
	used[v] = true;
	tin[v] = fup[v] = timer++;
	int children = 0;
	for (size_t i=0; i<g[v].size(); ++i) {
		int to = g[v][i];
		if (to == p)  continue;
		if (used[to])
			fup[v] = min (fup[v], tin[to]);
		else {
			dfs (to, v);
			fup[v] = min (fup[v], fup[to]);
			if (fup[to] >= tin[v] && p != -1)
				ans.push_back(v);
			++children;
		}
	}
	if (p == -1 && children > 1)
		ans.push_back(v);
}

void check(int v, int q, int t)
{
    used[v]=1;
    if (v==q) return;
    a1[v] += t;
    for (auto i:g[v])
    {
        if (!used[i]) check(i,q,t);
    }

}

int32_t main() {
    cin.tie(0);
    cout.tie(0);
    ios_base::sync_with_stdio(false);
	int q;
	cin >> q;

	for (int k=0; k<q; k++)
    {
        int n,m,a,b;
        cin >> n >> m >> a >> b;
        a--;
        b--;
        g.clear();
        ans.clear();
        g.resize(n);
        for (int i=0; i<m; i++)
        {
            int l,r;
            cin >> l >> r;
            l--;
            r--;
            g[l].push_back(r);
            g[r].push_back(l);
        }

        timer = 0;
        for (int i=0; i<n; i++) used[i]=false;
        dfs(0);
        bool ok = 0;
        bool ok1 = 0;
        for (auto i:ans)
        {
            if (i==a) ok=1;
            if (i==b) ok1=1;
        }

        if (!ok || !ok1)
        {
            cout << 0 << endl;
            continue;
        }

        for (int i=0; i<n; i++)
        {
            used[i]=0;
            a1[i]=0;
        }

        check(a,b,1);
        for (int i=0; i<n; i++) used[i]=false;
        check(b,a,2);
        int otv1 = 0;
        int otv2 = 0;
        for (int i=0; i<n; i++)
        {
            if (a1[i]==1) otv1++;
            if (a1[i]==2) otv2++;
        }

        cout << (otv1-1)*(otv2-1) << endl;
    }
}


#include <string>
#include <fstream>
#include <queue>
#include <iostream>
#include <algorithm>
#include <stack>
#include <vector>
#include <set>
#include <math.h>
#include <cmath>
#include <map>
#include <unordered_map>

using namespace std;

vector<int> used;
vector<int> used2;
vector<vector<int>> g;
int cnt = 0;
int cnt2 = 0;
int a, b;

void dfs(int v)
{
    used[v] = cnt;
    cnt2 += 1;
    for (int i = 0; i < g[v].size(); ++i)
    {
        if (used[g[v][i]] == -1 && g[v][i] != a && g[v][i] != b)
        {
            dfs(g[v][i]);
        }
    }
}

int main() {
    std::ios::sync_with_stdio(0);
    int t;
    cin >> t;
    vector<int> comp;
    vector<int> ar3;
    for (int q = 0; q < t; ++q)
    {
        int n, m;
        cin >> n >> m;
        cin >> a >> b;
        comp.resize(0);
        g.resize(n);
        cnt = 0;
        cnt2 = 0;
        for (int i = 0; i < n; ++i)
        {
            g[i].resize(0);
        }
        used = vector<int>(n, -1);
        a -= 1;
        b -= 1;
        for (int i = 0; i < m; ++i)
        {
            int v, u;
            cin >> v >> u;
            v--, u--;
            g[v].push_back(u);
            g[u].push_back(v);
        }
        for (int i = 0; i < n; ++i)
        {
            cnt2 = 0;
            if (used[i] == -1 && i != a && i != b)
            {
                used[i] = cnt;
                dfs(i);
                comp.push_back(cnt2);
                cnt += 1;
            }
        }
        int64_t ans1 = 0;
        ar3 = vector<int>(comp.size(), -1);
        int64_t ans2 = 0;
        for (int i = 0; i < g[a].size(); ++i)
        {
            if (g[a][i] == b)
                continue;
            else
            {
                if (ar3[used[g[a][i]]] == -1)
                {
                    ans1 += comp[used[g[a][i]]];
                    ar3[used[g[a][i]]] = 1;
                }
            }
        }
        for (int i = 0; i < g[b].size(); ++i)
        {
            if (g[b][i] == b)
                continue;
            else
            {
                if (ar3[used[g[b][i]]] == -1)
                {
                    ans2 += comp[used[g[b][i]]];
                    ar3[used[g[b][i]]] = 2;
                }
                else if (ar3[used[g[b][i]]] == 1)
                {
                    ans1 -= comp[used[g[b][i]]];
                    ar3[used[g[b][i]]] = 2;
                }
            }
        }
        cout << ans1 * ans2 << endl;
    }
}


#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

//ifstream in("input.txt");
//ofstream out("output.txt");

void dfs(vector<vector<int>>& g, vector<bool>& vis, int u, int& cnt)
{
	cnt++;
	vis[u] = true;
	for (int i = 0; i < g[u].size(); i++)
	{
		if (vis[g[u][i]] == false)
			dfs(g, vis, g[u][i], cnt);
	}
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int q; cin >> q;
	for (int qq = 0; qq < q; qq++)
	{
		int n, m, a, b;
		cin >> n >> m >> a >> b;
		vector<vector<int>> g(n);
		int u = 0, v = 0;
		for (int i = 0; i < m; i++)
		{
			cin >> u >> v;
			g[u - 1].push_back(v - 1);
			g[v - 1].push_back(u - 1);
		}
		vector<bool> vis(n, false);
		vis[a-1] = true; vis[b-1] = true;
		int cnt1 = 0;
		dfs(g, vis, a - 1, cnt1);
		for (int i = 0; i < n; i++)
			vis[i] = false;
		vis[a - 1] = true;
		vis[b - 1] = true;
		int cnt2 = 0;
		dfs(g, vis, b - 1, cnt2);
		int dif = cnt1 + cnt2 - n;
		cnt1 -= dif;
		cnt2 -= dif;
		cout << (long long)(cnt1 - 1) * (cnt2 - 1) << '\n';
	}
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//typedef int ll;
//typedef double ll;
//ll MAX = LLONG_MAX;
ll MAX = 1e15;

int main(){
    /*freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);*/
    ios_base::sync_with_stdio(0);

    ll q;
    cin >> q;
    while(q--){
        ll n,m,a,b;
        cin >> n >> m >> a >> b;
        a--;
        b--;
        vector<vector<ll>> g(n);
        for(ll i=0; i<m; i++){
            ll from, to;
            cin >> from >> to;
            from--;
            to--;
            g[from].push_back(to);
            g[to].push_back(from);
        }
        //BFS
        vector<ll> used(n,false);
        vector<ll> col(n,0);
        queue<ll> q;
        q.push(a);
        col[a]=1;
        while(!q.empty()){
            ll v = q.front();
            q.pop();
            for(ll i=0; i<g[v].size(); i++){
                ll to = g[v][i];
                if(!used[to] && to!=b){
                    col[to]=1;
                    used[to]=true;
                    q.push(to);
                }
            }
        }
        col[b]=2;
        //BFS-2
        for(ll i=0; i<n; i++){
            used[i]=false;
        }
        used[b]=true;
        q.push(b);
        while(!q.empty()){
            ll v = q.front();
            q.pop();
            for(ll i=0; i<g[v].size(); i++){
                /*if(v==b){
                    cout << g[v][i] << " ";
                }*/
                ll to = g[v][i];
                if(!used[to] && to!=a){
                    if(col[to]==1){
                        col[to]=3;
                    }
                    else {
                        col[to]=2;
                    }
                    used[to]=true;
                    q.push(to);
                }
            }
        }
        //cout << "\n";
        //COUNTING
        /*for(ll i=0; i<n; i++){
            cout << i+1 << ": " << col[i] << "  ";
        }
        cout << "\n\n";*/
        ll red=-1, white=-1;
        for(ll i=0; i<n; i++){
            if(col[i]==1){
                red++;
            }
            else if(col[i]==2) {
                white++;
            }
        }
        ll ans=red*white;
        cout << ans << "\n";
    }

    return 0;
}


#include <iostream>
#include <iomanip>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <string>
#include <stdio.h>
#include <set>
#include <map>
#include <algorithm>
#include <queue>
#include <vector>
#define ll long long
#define pb push_back
#define mp make_pair
#define f first
#define s second

using namespace std;

const int inf = 1e9 + 7;
const long long INF = 1e18 + 7;
const int maxn = 5e5 + 7;

int q, n, m, tin[maxn], timer, fup[maxn], a, b, c[maxn];
vector < int > g[maxn];
bool used[maxn];
int col[maxn];

void dfsx(int v){
	used[v] = 1;
	col[v] += 1;
	for (auto to : g[v]){
		if (to != b && !used[to])
			dfsx(to);
	}
}

void dfsy(int v){
	used[v] = 1;
	col[v] += 2;
	for (auto to : g[v]){
		if (to != a && !used[to])
			dfsy(to);
	}
}

int main(){
	ios_base::sync_with_stdio(NULL);
	cin.tie(0);
	cout.tie(0);
	cin >> q;
	while (q--){
		cin >> n >> m >> a >> b;
		timer = 1;
		for (int i = 1; i <= n; i++)
			g[i].clear(), tin[i] = 0, fup[i] = 0, used[i] = 0, col[i] = 0, c[i] = 0;
	   	for (int i = 1; i <= m; i++){
	   		int x, y;
	   		cin >> x >> y;
	   		g[x].pb(y);
	   		g[y].pb(x);
	   	}
	   	dfsx(a);
	   	memset(used, 0, sizeof(used));
	   	dfsy(b);
	   	ll x = 0, y = 0;
	   	for (int i = 1; i <= n; i++){
	   		if (col[i] == 1)
	   			x++;
	   		if (col[i] == 2)
	   			y++;
	   	}
	   	cout << (x - 1) * (y - 1) << '\n';
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
long long flag[200010];
long long tin[200010];
long long fup[200010];
long long color[200010];
long long answer1[200010];
long long answer2[200010];
long long tim;
long long n,m,a,b;
vector<long long> v[200010];

void dfs(long long x, long long predok) {
  color[x]=1;
  tin[x]=fup[x]=tim++;
  long long children=0;
  for (int i=0;i<v[x].size();i++) {
   long long to=v[x][i];
   if (to==predok)  continue;
	 if (color[to]) fup[x]=min(fup[x],tin[to]);
		else {
			dfs(to,x);
			fup[x]=min(fup[x],fup[to]);
			if (fup[to]>=tin[x] && predok!=-1)
				flag[x]=1;
			++children;
		}
	}
 if (predok==-1 && children>1) flag[x]=1;
}
void dfs2(long long x)
{
 answer1[x]=1;
 if (x==b) return;
 for(int i=0;i<v[x].size();i++)
  {
   int to=v[x][i];
   if(answer1[to]==0) dfs2(to);
  }
}
void dfs3(int x)
{
 answer2[x]=1;
 if (x==a) return;
 for(int i=0;i<v[x].size();i++)
  {
   int to=v[x][i];
   if(answer2[to]==0) dfs3(to);
  }
}
int main()
{
 //freopen("input.txt","r",stdin);
 //freopen("output.txt","w",stdout);
 ios_base::sync_with_stdio(0);
 long long t;
 cin>>t;
 while(t>0){t--;
  cin>>n>>m>>a>>b;
  for(int i=1;i<=n;i++){
   v[i].clear();
   color[i]=0;
   flag[i]=0;
   fup[i]=0;
   tin[i]=0;
   tim=0;
   answer1[i]=0;
   answer2[i]=0;
  }
  for(int i=1;i<=m;i++){
    long long x,y;
    cin>>x>>y;
    v[x].push_back(y);
    v[y].push_back(x);
  }
  dfs(1,-1);
  if (flag[a]+flag[b]!=2){cout<<0<<endl;continue;}
  //cout<<flag[a]<<' '<<flag[b]<<endl;
  dfs2(a);
  dfs3(b);
  long long kol1=0,kol2=0;
  for(int i=1;i<=n;i++){
   if(answer1[i]+answer2[i]==2) continue;
   if(answer1[i]>0) kol1++;
   if(answer2[i]>0) kol2++;
  }
  cout<<kol1*kol2<<endl;
 }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define f first
#define s second
#define pb push_back

void bfs(ll s,ll f,ll n,ll c,vector<ll> &cols,vector<vector<ll> > &g)
{
    queue <ll> q;
    q.push(s);
    vector<bool> u(n+1,false);
    u[s]=true;
    while(!q.empty())
    {
        ll v=q.front();
        q.pop();
        if(v==f) continue;
        if(cols[v]!=0) cols[v]=37894;
        else cols[v]=c;
        for(int i=0;i<g[v].size();i++)
        {
            ll x=g[v][i];
            if(!u[x])
            {
                q.push(x);
                u[x]=true;
            }
        }

    }
}

int main()
{
    ios_base::sync_with_stdio(false);
    ll q;
    cin>>q;
    while(q--)
    {
       ll n,m,x,y;
       cin>>n>>m>>x>>y;
       vector<vector<ll> > g;
vector<ll> cols;
       g.resize(n+1,vector<ll>(0));
       cols.resize(n+1,0);
       for(int i=1;i<=m;i++)
       {
           ll from,to;cin>>from>>to;
           g[from].pb(to);
           g[to].pb(from);
       }
       /*cols[x]=-1;
       cols[y]=-1;*/
       bfs(x,y,n,1,cols,g);
       bfs(y,x,n,2,cols,g);
       ll sch1=0,sch2=0;
       for(int i=1;i<=n;i++)
       {
           if(cols[i]==1) sch1++;
           if(cols[i]==2) sch2++;
       }
       cout<<(sch1-1)*(sch2-1)<<endl;
    }

    return 0;
}


#include <iostream>
#include <string>
#include <set>
#include <algorithm>
#include <vector>
#include <map>

#define ll long long

using namespace std;

vector<vector<ll>> lists;
ll n, m, a, b;
vector<bool> was;
vector<bool> was1;

void dfs(ll v) {
    if(!was[v]) {
//        cout << v << " 1" << endl;
        if(v != b) {
            was[v] = true;
            for(ll x : lists[v]) {
                dfs(x);
            }
        }
    }
}
void dfs1(ll v) {
    if(!was1[v]) {
//        cout << v << " 2" << endl;
        if(v != a) {
            was1[v] = true;
            for(ll x : lists[v]) {
                dfs1(x);
            }
        }
    }
}

void solve() {
    cin >> n >> m >> a >> b;
    --a;
    --b;
    lists = vector<vector<ll>>(n, vector<ll>());
    was = vector<bool>(n, false);
    was1 = vector<bool>(n, false);
    for(ll i = 0; i < m; ++i) {
        ll x, y;
        cin >> x >> y;
        --x;
        --y;
        lists[x].push_back(y);
        lists[y].push_back(x);
    }
    dfs(a);
    dfs1(b);
    ll c1 = 0;
    ll c2 = 0;
    for(ll i = 0; i < n; ++i) {
        if(was[i] && (!was1[i])) {
            ++c1;
        } else if((!was[i]) && was1[i]) {
            ++c2;
        }
    }
//    cout << c1 << ' ' << c2;
    --c1;
    --c2;
    cout << c1 * c2 << '\n';
}

int main() {
    ll t;
    cin >> t;
    for(ll i = 0; i < t; ++i) {
        solve();
    }
    return 0;
}


#include <iostream>
#include <vector>

#define int long long

using namespace std;

int c[1000000+5];

vector <int> ctp;

vector<vector<int> > g;
bool used[1000000+5];
int timer, tin[1000000+5], fup[1000000+5];

void dfs (int v, int p = -1)
{
    used[v] = true;
    tin[v] = fup[v] = timer++;
    int children = 0;
    for (size_t i=0; i<g[v].size(); ++i)
    {
        int to = g[v][i];
        if (to == p)  continue;
        if (used[to])
            fup[v] = min (fup[v], tin[to]);
        else
        {
            dfs (to, v);
            fup[v] = min (fup[v], fup[to]);
            if (fup[to] >= tin[v] && p != -1)
                ctp.push_back(v);
            ++children;
        }
    }
    if (p == -1 && children > 1)
        ctp.push_back(v);
}

void dfs1(int v, int q, int t)
{
    used[v]=true;
    if (v==q) return;
    c[v]+=t;
    for (auto i:g[v])
    {
        if (!used[i]) dfs1(i,q,t);
    }
}

int32_t main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int q;
    cin>>q;
    for (int o=0; o<q; o++)
    {
        int n,m,a,b;
        cin>>n>>m>>a>>b;
        a--;
        b--;
        g.clear();
        ctp.clear();
        g.resize(n);
        for (int i=0; i<m; i++)
        {
            int l,r;
            cin>>l>>r;
            l--;
            r--;
            g[l].push_back(r);
            g[r].push_back(l);
        }
        timer = 0;
        for (int i=0; i<n; ++i)
            used[i] = false;
        dfs(0);
        bool can=false;
        bool can1=false;
        for (int i=0; i<(int)ctp.size(); i++)
        {
            if (ctp[i]==a) can=true;
            if (ctp[i]==b) can1=true;
        }
        if (can==false||can1==false)
        {
            cout<<0<<'\n';
            continue;
        }
        for (int i=0; i<n; i++)
        {
            used[i]=false;
            c[i]=0;
        }
        dfs1(a,b,1);
        for (int i=0; i<n; i++)
        {
            used[i]=false;
        }
        dfs1(b,a,2);
        int ans1=0;
        int ans2=0;
        for (int i=0; i<n; i++)
        {
            if (c[i]==1) ans1++;
            if (c[i]==2) ans2++;
        }
        int ans=(ans1-1)*(ans2-1);
        cout<<ans<<'\n';
    }
}


#pragma optimize("SEX_ON_THE_BEACH")

//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC optimize("unroll-loops")
//#pragma comment(linker, "/STACK:256000000")

// EXTRA DANGEROUS BLOCK OF CODE
// UNCOMMENT ON YOUR OWN RISK

//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")
//#pragma GCC optimize("fast-math")
//#pragma GCC optimize("section-anchors")
//#pragma GCC optimize("profile-values,profile-reorder-functions,tracer")
//#pragma GCC optimize("vpt")
//#pragma GCC optimize("rename-registers")
//#pragma GCC optimize("move-loop-invariants")
//#pragma GCC optimize("unswitch-loops")
//#pragma GCC optimize("function-sections")
//#pragma GCC optimize("data-sections")
//#pragma GCC optimize("branch-target-load-optimize")
//#pragma GCC optimize("branch-target-load-optimize2")
//#pragma GCC optimize("btr-bb-exclusive")

#include <unordered_map>
#include <unordered_set>
#include <forward_list>
#include <algorithm>
#include <iostream>
#include <utility>
#include <bitset>
#include <random>
#include <string>
#include <vector>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <tuple>
#include <list>
#include <any>
#include <map>
#include <set>

using namespace std;

// DANGERZONE //
// UNCOMMENT IN EXTREME SITUATIONS //
// #define int long long
// DANGERZONE //

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, int> pli;
typedef pair<int, ll> pil;
typedef pair<ll, ll> pll;
typedef unsigned long long ull;

// DIRECTIVES END //

const ld pi = 3.1415926;
const int MOD = (int)(1e9) + 7;
const int INF = (int)(1e9) + 1e3;
const ll LINF = (ll)(1e18) + 1e6;
const int MAXN = (int)(1e5);
const int MAXQ = (int)(1e5);

struct dsu{
	vector<int> p;
	vector<int> sz;
	dsu(int n) : p(n + 1), sz(n + 1, 1) {
		for (int i = 1; i < p.size(); ++i) {
			p[i] = i;
		}
	}

	int find_set(int v) {
		if (v == p[v]) {
			return v;
		}
		return p[v] = find_set(p[v]);
	}

	void union_set(int u, int v) {
		u = find_set(u);
		v = find_set(v);
		if (u == v) {
			return;
		}
		if (sz[u] < sz[v]) {
			swap(u, v);
		}
		sz[u] += sz[v];
		p[v] = u;
	}
};

int n, m, a, b;

vector<int> used;
vector<vector<int> > graph;
void dfs(int v, dsu &d, int root) {
	used[v] = 1;
	for (int u : graph[v]) {
		if (used[u] && u != root && v != root) {
			d.union_set(u, v);
		} else if (!used[u]) {
			dfs(u, d, root);
		}
	}
}

void solve() {
	cin >> n >> m >> a >> b;
	dsu d1(n), d2(n);
	graph.resize(n + 1);
	used.resize(n + 1);
	for (int i = 0; i < m; ++i) {
		int u, v;
		cin >> u >> v;
		graph[u].push_back(v);
		graph[v].push_back(u);
	}
	dfs(a, d1, a);
	used.assign(n + 1, 0);
	dfs(b, d2, b);
	used.assign(n + 1, 0);
	ll cnt1 = 0, cnt2 = 0;
	int tb1 = d1.find_set(b), tb2 = d2.find_set(a);
	for (int i = 1; i <= n; ++i) {
		int p = d1.find_set(i);
		if (tb1 == p || p == a) {
			continue;
		}
		if (!used[p]) {
			used[p] = 1;
			cnt1 += d1.sz[p];
		}
	}
	used.assign(n + 1, 0);
	for (int i = 1; i <= n; ++i) {
		int p = d2.find_set(i);
		if (p == tb2 || p == b) {
			continue;
		}
		if (!used[p]) {
			used[p] = 1;
			cnt2 += d2.sz[p];
		}
	}
	cout << cnt1 * cnt2 << '\n';
	used.clear();
	graph.clear();
}

void isolve() {}

void generator() {}

void validator() {}

void stress() {}

signed main() {
    ios_base::sync_with_stdio(false);
    srand(time(nullptr));
    cout.setf(ios::fixed);
    cout.precision(10);
    cout.tie(nullptr);
    cin.tie(nullptr);
#ifdef M8_LOCAL
    freopen("input.in", "r", stdin);
    freopen("output.out", "w", stdout);
#endif
    // -----------------------

    int T = 1;
    cin >> T;
    while(T--) {
        solve();
    }

    // -----------------------
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef tuple<int, int, int> tiii;
typedef tuple<int, int, int, int> tiiii;
typedef set <int> si;
typedef map <int, int> mii;
typedef vector <int> vi;
typedef vector <ll> vll;
typedef vector <vector <int>> vvi;
#define F(i, a, b) for(int i = a; i <= (int)b; i++)
#define f(i, a, b) for(int i = a; i >= (int)b; i--)
#define F2(i, a, b) for(int i = a; i <= (int)b; i+=2)
#define f2(i, a, b) for(int i = a; i >= (int)b; i-=2)
#define wh(n) int iteration = n; while(iteration--)
#define For(t, it) for(auto it = (t).begin(); it != (t).end(); ++it)
#define IN insert
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define RS resize
#define GRAF(n) vvi gr; gr.resize(n+1); vector <bool> was; was.resize(n+1, 0);

bool was[200007];
vvi gr;

int type, a, b;
int sz;
ll N[4];

void dfs(int v){
	was[v] = 1;
	sz++;
	F(i, 0, gr[v].size()-1){
		int to = gr[v][i];
		if(!was[to]){
			if(to == a)
				if(type / 2 == 0)
					type += 2;
			if(to == b)
				if(type % 2 == 0)
					type++;
			if(to != a && to != b)
				dfs(to);
		}
	}
}

ll solve(){
	int n, m, c, d;
	cin >> n >> m >> a >> b;
	F(i, 0, 3)
		N[i] = 0;
	gr.clear();
	gr.RS(n+1);
	F(i, 1, n)
		was[i] = 0;
	F(i, 1, m){
		cin >> c >> d;
		gr[c].PB(d);
		gr[d].PB(c);
	}
	F(i, 1, n){
	 	if(i != a && i != b && !was[i]){
	 		type = 0, sz = 0;
	 		dfs(i);
	 		N[type] += sz;
	 	}
	}
	return N[1]*1ll*N[2];
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
        #ifdef LOCAL
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
	#endif
	int t;
	cin >> t;
	wh(t)
		cout << solve() << '\n';
	return 0;
}


#include <bits/stdc++.h>
#define int long long

using namespace std;

int timer = 0, clr = 0, res1 = 0, res2 = 0;
vector <int> tin, up;
set <int> cp;

void dfs(vector < vector <int> > &g, vector <int> &used, int v, int from = -1) {
    used[v] = 1;
    tin[v] = timer++;
    up[v] = tin[v];
    int cnt = 0;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs(g, used, to, v);
            up[v] = min(up[v], up[to]);
            if (tin[v] <= up[to] && from != -1) {
                cp.insert(v);
            }
            cnt++;
        } else {
            if (to != from) {
                up[v] = min(tin[to], up[v]);
            }
        }
    }
    if (from == -1 && cnt > 1) {
        cp.insert(v);
    }
}

int cnt = 0, flag = 0;

void dfs_a(vector < vector <int> > &g, vector <int> &used, int v, int a, int b) {
    if (v != a) cnt++;
    used[v] = 1;
    for (int to : g[v]) {
        if (v == a) flag = 0;
        if (to == b) {
            flag = 1;
            continue;
        }
        if (!used[to]) {
            dfs_a(g, used, to, a, b);
            if (v == a) {
                if (!flag) {
                    res1 += cnt;
                }
                cnt = 0;
                flag = 0;
            }
        }
    }
}

void dfs_b(vector < vector <int> > &g, vector <int> &used, int v, int a, int b) {
    if (v != b) cnt++;
    used[v] = 1;
    for (int to : g[v]) {
        if (v == b) flag = 0;
        if (to == a) {
            flag = 1;
            continue;
        }
        if (!used[to]) {
            dfs_b(g, used, to, a, b);
            if (v == b) {
                if (!flag) {
                    res2 += cnt;
                }
                cnt = 0;
                flag = 0;
            }
        }
    }
}

main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int t;
    cin >> t;
    while (t--) {
        timer = 0, res1 = 0, res2 = 0;
        int n, m, a, b;
        cin >> n >> m >> a >> b;
        cp.clear();
        tin.assign(n, 0);
        up.assign(n, 0);
        vector < vector <int> > g(n);
        for (int i = 0; i < m; i++) {
            int c, d;
            cin >> c >> d;
            g[c - 1].push_back(d - 1);
            g[d - 1].push_back(c - 1);
        }
        vector <int> used(n);
        for (int i = 0; i < n; i++) {
            if (!used[i]) {
                dfs(g, used, i);
            }
        }
        if (cp.find(a - 1) == cp.end() || cp.find(b - 1) == cp.end()) {
            cout << 0 << '\n';
            continue;
        }
        used.assign(n, 0);
        dfs_a(g, used, a - 1, a - 1, b - 1);
        cnt = 0, flag = 0;
        dfs_b(g, used, b - 1, a - 1, b - 1);
        cout << res1 * res2 << '\n';
    }
}


#include <bits/stdc++.h>
#include <random>
#include <chrono>

//#pragma comment(linker, "/STACK:16777216")

using namespace std;

typedef long double C;
typedef complex<C> P;

#define X real()
#define Y imag()

#define ui unsigned int
#define int long long
#define mp make_pair
#define timer fghge
#define y1 yjyjyju
#define have(X, a) (X.find(a) != X.end())
#define Size(X) (int)X.size()
#define all(X) (X).begin(), (X).end()
#define endl '\n'
mt19937_64 rnd(std::chrono::system_clock::now().time_since_epoch().count());

struct node {
	bool used = 0;
	vector<int> edjes;
};
int ctr = 0;
void dfs(int start, vector<node> &g, int bad) {
	g[start].used = 1;
	ctr++;
	for (auto &i : g[start].edjes) {
		if (g[i].used == 1 || i == bad)
			continue;
		dfs(i, g, bad);
	}
}

signed main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	//freopen("input.txt", "r", stdin);
	//freopen("input.txt", "w", stdout);

	int t; cin >> t;
	while (t--) {
		int n, m, a, b;
		cin >> n >> m >> a >> b; a--; b--;
		vector<node> g(n);
		for (int i = 0; i < m; i++) {
			int fir, sec; cin >> fir >> sec; fir--; sec--;
			g[fir].edjes.push_back(sec);
			g[sec].edjes.push_back(fir);
		}
		int fir, sec;
		for (auto &i : g)
			i.used = 0;
		ctr = 0;
		dfs(a, g, b);
		fir = n - ctr - 1;
		for (auto &i : g)
			i.used = 0;
		ctr = 0;
		dfs(b, g, a);
		sec = n - ctr - 1;
		cout << fir * sec << endl;
	}
	return 0;
}


//#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
#include <iostream>
#include <vector>
#include <set>
#include <queue>
#include <algorithm>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
//#define int ll
//#define ull ll

const int Inf = 1e9 + 7;

inline void boost_in_out()
{
	ios_base::sync_with_stdio(0);
	cin.tie(NULL);
	cout.tie(NULL);
	cerr.tie(NULL);
}

vector<int> used;
vector<vector<int>> g;

void dfs(int v, int fb)
{
	used[v] = 1;
	for (int to: g[v])
	{
		if (!used[to] && to != fb)
			dfs(to, fb);
	}
}

signed main()
{
	boost_in_out();
	int t;
	cin >> t;
	for (int iii = 0; iii < t; ++iii)
	{
		int n, m, a, b;
		cin >> n >> m >> a >> b;
		used.assign(n, 0);
		g.assign(n, vector<int>());
		--a;
		--b;
		for (int i = 0; i < m; ++i)
		{
			int x, y;
			cin >> x >> y;
			--x;
			--y;
			g[x].push_back(y);
			g[y].push_back(x);
		}
		dfs(a, b);
		ll c1 = -1, c2 = -1;
		for (int i = 0; i < n; ++i)
		{
			if (!used[i])
			{
				++c1;
			}
		}
		used.assign(n, 0);
		dfs(b, a);
		for (int i = 0; i < n; ++i)
		{
			if (!used[i])
			{
				++c2;
			}
		}
		cout << c1 * c2 << '\n';
	}
	return 0;
}


#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef vector<int> vi;

int n, m, a, b;
vector< vector<int> > d;
vector<bool> used;
vector<bool> to_a_no_b;
vector<bool> to_b_no_a;

void dfs_to_a(int v)
{
    if (used[v] || v == b)
        return;

    used[v] = true;
    if (v != a) to_a_no_b[v] = true;

    auto roads = d[v];
    for (int i = 0; i < roads.size(); i++)
        dfs_to_a(roads[i]);
}

void dfs_to_b(int v)
{
    if (used[v] || v == a)
        return;

    used[v] = true;
    if (v != b) to_b_no_a[v] = true;

    auto roads = d[v];
    for (int i = 0; i < roads.size(); i++)
        dfs_to_b(roads[i]);
}

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int t;
    cin >> t;
    while (t--)
    {
        cin >> n >> m >> a >> b;
        d = vector< vector<int> >(n+1, vector<int>(0));
        for (int i = 0; i < m; i++)
        {
            int u, v;
            cin >> u >> v;
            d[u].push_back(v);
            d[v].push_back(u);
        }

        used = vector<bool>(n+1, false);
        to_a_no_b = vector<bool>(n+1, false);
        dfs_to_a(a);
        fill(used.begin(), used.end(), false);
        to_b_no_a = vector<bool>(n+1, false);
        dfs_to_b(b);

        int only_a = 0;
        int only_b = 0;
        for (int i = 1; i <= n; i++)
        {
            if (to_a_no_b[i] && !to_b_no_a[i])
                only_a++;
            else if (to_b_no_a[i] && !to_a_no_b[i])
                only_b++;
        }

        cout << only_a * only_b << '\n';
    }

    return 0;
}


#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include<map>
#include<set>
#include<cmath>
#include<queue>

using namespace std;

#define int long long

vector<vector<int>> g;
vector<int> used(2 * 1e5 + 1, 0);
int a, b;
int nw = 0;
int nwsz = 0;
int vb = 0, va = 0;

void dfs(int v) {
	used[v] = nw;
	nwsz++;
	if (v == a) {
		va = 1;
	}
	else if (v == b) {
		vb = 1;
	}
	for (auto u : g[v]) {
		if (used[u] < nw) {
			dfs(u);
		}
	}
}

signed main() {
	int t;
	cin >> t;
	for (int k = 0; k < t; k++) {
		int n, m;
		cin >> n >> m >> a >> b;
		g.clear();
		g.resize(n);
		a--;
		b--;
		for (int i = 0; i < m; i++) {
			int u, v;
			cin >> u >> v;
			u--;
			v--;
			g[u].push_back(v);
			g[v].push_back(u);
		}
		nw++;
		int szb = 0;
		int sza = 0;
		va = 0;
		vb = 0;
		nwsz = 0;
		used[a] = nw;
		for (auto u : g[a]) {
			if (used[u] < nw) {
				dfs(u);
				if (vb == 1) {
					vb = 0;
				}
				else {
					sza += nwsz;
				}
				nwsz = 0;
			}
		}
		nw++;
		va = 0;
		vb = 0;
		nwsz = 0;
		used[b] = nw;
		for (auto u : g[b]) {
			if (used[u] < nw) {
				dfs(u);
				if (va == 1) {
					va = 0;
				}
				else {
					szb += nwsz;
				}
				nwsz = 0;
			}
		}
		cout << sza * szb << "\n";
	}

}


//#define _CRT_SECURE_NO_WARNINGS
#pragma warning (disable:4996)

#include <iostream>
#include <ctime>
#include <iomanip>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <queue>

#define all(x) x.begin(), x.end()
#define allr(x) x.rbegin(), x.rend()

using namespace std;

typedef long long ll;
typedef double long dl;

const int MAXN = (int)1e9 + 1;
const int INF = (int)1e9 + 7;
const ll MAXSIZE = 400000;

void input() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
#ifdef _DEBUG
	freopen("input", "r", stdin);
	freopen("output", "w", stdout);
#endif
}

ll mod(ll x, ll m) {
	return (x % m + m) % m;
}

void dfs(int v, const vector<set<ll>>& graph, vector<int>& used, const bool a) {
	if (used[v] != 0)
		return;
	if (a)
		used[v] = 1;
	else
		used[v] = 2;
	for (auto i : graph[v]) {
		dfs(i, graph, used, a);
	}
}

int main() {
	input();
	int q;
	cin >> q;
	for (int pq = 0; pq < q; pq++) {
		int n, m, a, b;
		cin >> n >> m >> a >> b;
		a--;
		b--;
		vector <set<ll>> graph(n);
		for (int i = 0; i < m; i++) {
			int v1, v2;
			cin >> v1 >> v2;
			v1--, v2--;
			graph[v1].insert(v2);
			graph[v2].insert(v1);
		}
		vector<int> used1(n, 0);
		vector<int> used2(n, 0);
		used2[a] = 4;
		used1[b] = 4;
		dfs(a, graph, used1, true);
		for (int i = 0; i < n; i++) {
			if (used1[i] == 0)
				used1[i] = 2;
		}
		used1[a] = 5;
		dfs(b, graph, used2, false);
		for (int i = 0; i < n; i++) {
			if (used2[i] == 0)
				used2[i] = 1;
		}
		used2[b] = 5;
		vector<ll> cnt(3, 0);
		for (int i = 0; i < n; i++) {
			if (used1[i] == used2[i])
				cnt[used1[i]]++;
		}
		cout << cnt[1] * cnt[2] << '\n';
	}
	return 0;
}


// copied by Nurstan Duisengaliev
// skatal
#include <bits/stdc++.h>

#define ll long long
#define all(x) x.begin(), x.end()
#define in insert
#define mp make_pair
#define F first
#define S second
#define ppf pop_front
#define pb push_back
#define ppb pop_back
#define pf push_front
#define pii pair <int, int>
#define boost() ios_base::sync_with_stdio(0), cin.tie(0)
#define sz(x) x.size()
#define int ll
using namespace std;

const int N = (int)2e5 + 123;
const int mod = (int)1e9 + 7;
const ll INF = (ll)1e18 + 7;
vector <int> g[N];
set <int> s[N];
bool used[N];
int tin[N], f[N], timer = 1;
int len[N];
int ans;
int vv;
int n, m, a, b;
void dfs (int v, int p, int t) {
	used[v] = 1;
	tin[v] = timer ++;
	f[v] = tin[v];
	len[v] = 1;
	if (v == b) vv = t;
	for (int i = 0; i < sz (g[v]); i ++) {
		int to = g[v][i];
		if (used[to] == 0) {
			if (v != a) {
				dfs (to, v, t);
			}
			else dfs (to, v, to);
			len[v] += len[to];
			f[v] = min (f[v], f[to]);
			if (v == b) {
				if (f[to] >= tin[v]) ans += len[to];
			}
		}
		else if (to != p) {
			f[v] = min (f[v], tin[to]);
		}
	}

}
void solve () {
	cin >> n >> m >> a >> b;
	timer = 1;
	ans = 0;
	for (int i = 1; i <= n; i ++) {
		used[i] = 0;
		g[i].clear ();
		s[i].clear ();
	}
	for (int i = 1; i <= m; i ++) {
		int l, r;
		cin >> l >> r;
		if (s[l].count (r) == 0) {
			g[l].pb (r);
			g[r].pb (l);
			s[l].in (r);
			s[r].in (l);
		}
	}
	dfs (a, -1, -1);
	cout << ans * (n - 1 - len[vv]) << endl;
}

main () {
//	freopen (".in", "r", stdin);
//	freopen (".out", "w", stdout);
	boost ();
	int TT;
    cin >> TT;
	while (TT --) {
	    solve ();
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

vector <vector <int> > g;
vector<int> used;
set<int> fs;
set<int> ss;
int a, b;

void dfsa(int v) {
    used[v] = true;
    for (auto &u : g[v]) {
        if (!used[u] && u != a) {
            dfsa(u);
            fs.insert(u);
        }
    }
}

void dfsb(int v) {
    used[v] = true;
    for (auto &u : g[v]) {
        if (!used[u] && u != b) {
            dfsb(u);
            ss.insert(u);
        }
    }
}

signed main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        int n, m;
        scanf("%d%d%d%d",&n,&m,&a,&b);
        a--;
        b--;
        g.assign(n+1,{});
        used.assign(n+1,0);
        fs.clear();
        ss.clear();
        for (int i = 0; i < m; i++) {
            int u, v;
            scanf("%d%d", &u,&v);
            g[u - 1].emplace_back(v - 1);
            g[v - 1].emplace_back(u - 1);
        }
        dfsb(a);
        used.assign(n+1,0);
        dfsa(b);
        int aa = 0, bb = 0;
        for (auto &e : fs) {
            if (ss.find(e) == ss.end()) {
                aa++;
            }
        }
        for (auto &e : ss) {
            if (fs.find(e) == fs.end()) {
                bb++;
            }
        }
        cout << 1LL * aa * bb << '\n';
    }
}


#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define eb emplace_back
#define pb push_back
#define pii pair<int,int>
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define mt make_tuple
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("avx2")

#define pcc pair<char,char>
using namespace std;

vector< vector<int> > g;
vector<int> col;
vector<int> used;

void dfs(int v, int c){
	col[v]+=c;
	used[v] = 1;
	for(auto t:g[v]){
		if(!used[t]) dfs(t,c);
	}
}

main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int t;
	cin>>t;
	while(t--){
		int n,m,a,b;
		cin>>n>>m>>a>>b;
		a--;b--;
		g.assign(n,vector<int>());
		col.assign(n,0);
		col[a] = 100;
		col[b] = 101;
		for(int i = 0; i < m; i++){
			int x,y;
			cin>>x>>y;
			x--;y--;
			if(x!=a && x!=b){
				g[y].pb(x);
			}
			if(y!=a && y!=b){
				g[x].pb(y);
			}
		}
		used.assign(n,0);
		dfs(a,1);
		used.assign(n,0);
		dfs(b,2);
		ll sz1 = 0;
		ll sz2 = 0;
		for(int i = 0; i < n; i++){
			if(col[i]==1) sz1++;
			if(col[i]==2) sz2++;
		}
		cout<<sz1*sz2<<"\n";
	}
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ii pair <int, int>
#define app push_back
#define all(a) a.begin(), a.end()
#define bp __builtin_popcount
#define ll long long
#define mp make_pair
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound
#define Time (double)clock()/CLOCKS_PER_SEC

const int N = 2e5 + 7;
vector<int> g[N];
bool used[N];
int timer, tin[N], fup[N];
int cnt[N], dp[N];
bool inp[N];
int color[N];
int n, m, a, b;
void dfs(int v, int p = -1) {
    used[v] = true;
    tin[v] = fup[v] = timer++;
    cnt[v] = 1;
    for (size_t i=0; i<g[v].size(); ++i) {
        int to = g[v][i];
        if (to == p)  continue;
        if (color[to] != color[v]) {
            fup[v] = -1;
            continue;
        }
        if (used[to])
            fup[v] = min (fup[v], tin[to]);
        else {
            dfs (to, v);
            cnt[v] += cnt[to];
            fup[v] = min (fup[v], fup[to]);
            if (fup[to] >= tin[v]) {
                dp[v] += cnt[to];
            }
        }
    }
}
vector <int> path, cur;
void go(int u, int want) {
    cur.app(u);
    if (want == u) path = cur;
    used[u] = 1;
    for (int v : g[u])
        if (!used[v])
            go(v, want);
    cur.pop_back();
}

bool tc = 0;
void col(int u, int c) {
    used[u] = 1;
    if (color[u] != -1)
        tc = 1;
    color[u] = c;
    for (int v : g[u])
        if (!inp[v] && !used[v])
            col(v, c);
}

signed main() {
    #ifdef HOME
    freopen("input.txt", "r", stdin);
    #else
    ios_base::sync_with_stdio(0); cin.tie(0);
    #endif
    int t;
    cin >> t;
    while (t--) {
        cin >> n >> m >> a >> b;

        timer = 0; tc = 0;
        for (int u = 1; u <= n; ++u) {
            cnt[u] = dp[u] = tin[u] = fup[u] = used[u] = inp[u] = 0;
            color[u] = -1;
            g[u].clear();
        }

        for (int i = 0; i < m; ++i) {
            int u, v;
            cin >> u >> v;
            g[u].app(v); g[v].app(u);
        }
        for (int i = 0; i <= n; ++i)
            used[i] = 0;
        go(a, b);
        for (int e : path) {
            inp[e] = 1;
            color[e] = 0;
        }

        for (int i = 0; i <= n; ++i)
            used[i] = 0;
        col(a, 1);
        for (int i = 0; i <= n; ++i)
            used[i] = 0;
        col(b, 2);

        for (int i = 0; i <= n; ++i)
            used[i] = 0;
        dfs(a);
        for (int i = 0; i <= n; ++i)
            used[i] = 0;
        dfs(b);

        cout << dp[a] * dp[b] << '\n';
    }
}


#include <stdio.h>
#include <bits/stdc++.h>

using namespace std;

#define ll long long

const int inf = (int)1e9;
const int mod = (int)1e9 + 9;

vector <vector <int> > e;
vector <int> used, tin, fup;

int timer;

set <int> pp;

void dfs(int v, int p = -1) {

	used[v] = 1;
	tin[v] = fup[v] = timer++;

	int children = 0;

	for (int to: e[v]) {

		if (to == p){
            continue;
		}
		if (used[to]) {
            fup[v] = min(fup[v], tin[to]);
		}
		else {
			dfs (to, v);
			fup[v] = min(fup[v], fup[to]);
			if (fup[to] >= tin[v] && p != -1) {
                pp.insert(v);
			}
			++children;
		}
	}

	if (p == -1 && children > 1) {
        pp.insert(v);
	}

    return;
}

vector <int> color;

void dfs_a(int v, int b) {

    used[v] = 1;

    for(int to: e[v]) {

        if(used[to] == 1 || to == b) {
            continue;
        }

        ++color[to];
        dfs_a(to, b);
    }

    return;
}

void dfs_b(int v, int a) {

    used[v] = 1;

    for(int to: e[v]) {

        if(used[to] == 1 || to == a) {
            continue;
        }

        color[to] += 2;
        dfs_b(to, a);
    }

    return;
}

int main() {
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    int q;
    scanf("%d", &q);

    while(q--) {

        int n, m, a, b;
        scanf("%d%d%d%d", &n, &m, &a, &b);

        --a, --b;

        e.assign(n, vector <int> (0, 0));
        while(m--) {

            int x, y;
            scanf("%d%d", &x, &y);

            e[x - 1].push_back(y - 1);
            e[y - 1].push_back(x - 1);
        }

        timer = 0;
        used.assign(n, 0);
        tin.assign(n, 0);
        fup.assign(n, 0);
        dfs(0);

        if(pp.find(a) == pp.end() || pp.find(b) == pp.end()) {
            printf("0\n");
            continue;
        }

        color.assign(n, 0);

        used.assign(n, 0);
        dfs_a(a, b);

        used.assign(n, 0);
        dfs_b(b, a);

        int num_a = 0;
        int num_b = 0;

        for(int x: color) {
            if(x == 1) {
                ++num_a;
            }
            if(x == 2) {
                ++num_b;
            }
        }

        printf("%I64d\n", 1ll * num_a * num_b);
    }

    return 0;
}


#include <algorithm>
#include <stdio.h>
#include <iostream>
#include <vector>
#include <cmath>
#include <math.h>
#include <queue>
#include <set>
#include <iterator>
#include <string>
#include <functional>
#include <array>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>

using namespace std;

#define pb push_back
#define ll long long

vector<long long> res;
vector<vector<int>> g;
vector<int> used_a, used_b, used;
int a, b, color = 1;

void dfs_a(int u) {
	if (!used_a[u]) {
		used_a[u] = 1;
		for (auto e : g[u]) {
			if (e == b) continue;
			dfs_a(e);
		}
	}
	return;
}

void dfs_b(int u) {
	if (!used_b[u]) {
		used_b[u] = 1;
		for (auto e : g[u]) {
			if (e == a) continue;
			dfs_b(e);
		}
	}
	return;
}

void dfs(int u) {
	if (!used[u]) {
		used[u] = color;
		for (auto e : g[u]) {
			if (e == a || e == b || (used_a[e] && used_b[e])) continue;
			dfs(e);
		}
	}
	return;
}

void go() {
	int n, m;
	cin >> n >> m >> a >> b;
	a--;
	b--;
	g.resize(n);
	used_a.assign(n, 0);
	used_b.assign(n, 0);
	used.assign(n, 0);
	for (int i = 0; i < n; i++) {
		g[i].clear();
	}
	int c, d;
	while(m--) {
		cin >> c >> d;
		c--;
		d--;
		g[c].pb(d);
		g[d].pb(c);
	}
	dfs_a(a);
	dfs_b(b);
	int ans1 = 0;
	int ans2 = 0;
//	for (int i = 0; i < n; i++) {
//		cout << used_a[i] << " ";
//	}
//	cout << "\n";
//	for (int i = 0; i < n; i++) {
//		cout << used_b[i] << " ";
//	}
//	cout << "\n";
	for (int i = 0; i < n; i++) {
		if (i == a || i == b) continue;
		if (used_a[i] == 0 && used_b[i] == 1) {
			ans2++;
		}
		if (used_a[i] == 1 && used_b[i] == 0) {
			ans1++;
		}
	}
	res.pb( (long long) ans1 * ans2);
}

signed main() {
	int t;
	cin >> t;
	while (t--) {
		go();
	}
	for (auto e : res) {
		cout << e << "\n";
	}
    return 0;
}


#include <bits/stdc++.h>

#define Solved int main()
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define SpeedForce ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define forn(i, x) for(int i = 1; i <= x; i++)
#define rep(i, x, y) for(int i = x; i <= y; i++)
#define sz(x) (int)x.size()
#define pii pair<int, int>
#define pll pair<ll, ll>
#define ll long long
#define ull unsigned long long
#define ld long double
#define mii map<int, int>
#define all(x) x.begin(), x.end()
#define lb lower_bound
#define ub upper_bound
using namespace std;

inline ll bip(ll x,ll n,ll mod){ll res=1;while(n){if(n&1){res=(res*x)%mod;}x=(x*x)%mod;n>>=1;}return res;}

const int maxn = 1e9;
const ll inf = 1e18;
//const int mod = 998244353;
const int mod = 1e9 + 7;
const int N = 2e5 + 10;

int n, m, a, b;
int was[N];
vector <int> g[N];

void dfs(int v, int t) {
    was[v] += t;
    if (t == 1 && v == b) return;
    if (t == 2 && v == a) return;

    for (auto to: g[v]) {
        if (!was[to] || (t == 2 && was[to] == 1)) {
            dfs(to, t);
        }
    }
}

void solve() {
    cin >> n >> m >> a >> b;

    memset(was, 0, sizeof was);
    for (int i = 1; i <= n; i++)
        g[i].clear();

    for (int i = 1; i <= m; i++) {
        int x, y;
        cin >> x >> y;
        g[x].pb(y);
        g[y].pb(x);
    }

    dfs(a, 1);
    dfs(b, 2);

    int l = 0, r = 0;
    for (int i = 1; i <= n; i++) {
        if (was[i] == 1 && i != a && i != b) l++;
        else if (was[i] == 2 && i != a && i != b) r++;
    }

    cout << l * 1ll * r;
}

Solved {
    SpeedForce;
	int tt = 1;
    cin >> tt;
	while (tt--) {
		solve();
		cout << '\n';
	}

}


#pragma GCC optimize("O3")
#pragma GCC target("mmx,sse,sse2,sse3,ssse3,sse4,avx,aes,pclmul,sse4.1,sse4.2")

#include<bits/stdc++.h>
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_DISABLE_PERFCRIT_LOCKS
#define cdbg cerr << "Debug in " << __func__ << ", " << __LINE__ << ": "
#define q <<  '\n'
#define sp << ' '
#define mp make_pair
#define pb emplace_back
#define ft first
#define sd second
#define ld long double
#define ll long long
#define ull unsigned long long
#define lll __int128
#define pii pair<ll , ll>
#define vi vector<int>
#define y1 trymaxlox

using namespace std;

const int N = 5e5;
const ll INF = 1e18 + 7;
const int MOD = 1e9+7;

ll n, m, k, a, b, c, d, arr[N], res, kek, t ;
set<ll> st;
string str;
vi ans, v;
set<int> g[N];
bool used[N], used2[N];

void del(int v)
{
    if (v == a || v == b) return;
   // cdbg << v q;
    used2[v] = 1;
    vi vv;
    for (int it : g[v])
    {
        if (!used2[it])
        {
            if (it != a && it != b) del(it);
            vv.pb(it);
        }
    }
     for (int i : vv)
    {
        g[v].erase(i);
        g[i].erase(v);
    }

}
vi vv;
bool dfsdel(int a, int v, int b, int p)
{
  //  cdbg << v q;
    used[v] = 1;
    bool f = 0, ff = 0;
//    cout << "! ! ";
//    for (auto it : g[v]) cout << it sp;
//    cout q;
    for (auto it : g[v])
    {
        //cdbg << "  " << it q;
        if (!used[it])
        {
            if (it == b)
            {
                f = 1;
                if (v != a) ff = 1;
            }
            else
            {
                dfsdel(a, it, b, v);
            }
        }
    }
    if (f && v != a && v != b)
    {
        vv.pb(v);
    }
    else if (f)
    {
        g[a].erase(b);
        g[b].erase(a);
    }
    //cdbg << v sp << f q;
    return f;
}

ll dfs(int v)
{
   // cdbg << v q;
    used[v] = 1;
    ll ans = 0;
    for (auto it : g[v])
    {
        if (!used[it])
        {
            ans += dfs(it);
        }
    }
    return ans + 1;
}
main()
{
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);

        cin >> t;
        while (t--)
        {
            cin >> n >> m >> a >> b;
            for (int i = 0;i <= n; i++)
            {
                g[i].clear();
            }
           // cdbg << "a" q;
           vv.clear();
            memset(used, 0, sizeof(used));
            memset(used2, 0, sizeof(used2));
            ll x , y;
            for (int i = 0; i < m; i++)
            {
                cin >> x >> y;
                g[x].insert(y);
                g[y].insert(x);
            }
            //cdbg << "aaa" q;
            dfsdel(a, a, b, a);
            for (auto it : vv)
            {
             //   cdbg << it q;
                del(it);
            }
            memset(used, 0, sizeof(used));
            ll cnta = dfs(a);
            cnta--;
            memset(used, 0, sizeof(used));
            ll cntb = dfs(b);
            cntb--;
            cout << cnta * cntb q;
        }

/*
3
a???cb
a??bbc
a?b?c
*/

}


#include <iostream>
#include <vector>
#include <map>

#define pb push_back
#define int long long

using namespace std;

vector <int> usd;
vector < vector <int> > g;
int cnt = 0;

vector <int> used;

void dfs(int v, int zapr) {
    if(v == zapr) return;
    usd[v] = 1;
    for(auto u : g[v]) {
        if(u == zapr) continue;
        if(!usd[u]) {
            dfs(u, zapr);
        }
    }
}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int t; cin >> t; while(t--) {
        int n, m;
        cin >> n >> m;
        int a, b;
        cin >> a >> b; a--; b--;
        g.assign(n, vector <int>(0));
        for(int i = 0; i < m; ++i) {
            int u, v;
            cin >> u >> v;
            v--;u--;
            g[u].pb(v);
            g[v].pb(u);
        }
        usd.assign(n, 0);
        dfs(a, b);
        used = usd;
        usd.assign(n, 0);
        dfs(b, a);
        int x = 0, y = 0;
//        for(auto i : usd) cout << i << " "; cout << "\n";
//        for(auto i : used) cout << i << " "; cout << "\n";
        for(int i = 0; i < n; ++i) {
            if(i == a || i == b) continue;
            if(usd[i] && !used[i]) {
                x++;
            } else {
                if(used[i] && !usd[i]) {
                    y++;
                }
            }
        }
//        cout << x << " " << y << "\n";
        cout << x * y << "\n";
    }

    return 0;
}


#include <bits/stdc++.h>
#define int long long
#define mp make_pair
#define eb emplace_back
#define pb push_back
#define pf push_front
#define x first
#define y second

typedef long long ll;

using namespace std;

const int inf = 1e10;
const int M = 998244353;
const long double pi = 3.14159265358979323846;

void dfs(int v, vector<bool> &used, vector<vector<int>> &sl, vector<int> &cmp){
    used[v] = true;
    cmp.eb(v);
    for(int u: sl[v]){
        if(!used[u])dfs(u, used, sl, cmp);
    }
}

main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    for(; t; --t){
        int n, m, a, b;
        cin >> n >> m >> a >> b;
        --a;
        --b;
        vector<bool> ia(n), ib(n);
        vector<vector<int>> sl(n);
        for(int i = 0; i < m; ++i){
            int u, v;
            cin >> u >> v;
            --u;
            --v;
            if(u == a){
                ia[v] = true;
            }
            if(u == b){
                ib[v] = true;
            }
            if(v == b){
                ib[u] = true;
            }
            if(v == a){
                ia[u] = true;
            }
            if(v != a && v != b && u != a && u != b){
                sl[v].eb(u);
                sl[u].eb(v);
            }
        }
        vector<vector<int>> cmp(n);
        int c = 0;
        vector<bool> used(n);
        for(int i = 0; i < n; ++i){
            if(!used[i] && i != a && i != b){
                dfs(i, used, sl, cmp[c++]);
            }
        }
        vector<bool> ta(cmp.size()), tb(cmp.size());
        int ra = 0, rb = 0;
        for(int i = 0; i < c; ++i){
            for(int e: cmp[i]){
                ta[i] = ta[i] || ia[e];
                tb[i] = tb[i] || ib[e];
            }
            if(tb[i] && ta[i])continue;
            if(tb[i])rb += cmp[i].size();
            else ra += cmp[i].size();
        }
        cout << ra * rb << "\n";
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define ld long double

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast, no-stack-protector, unroll-loops, fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

mt19937 gen(chrono::steady_clock::now().time_since_epoch().count());

ll INF = (ll) 1e20;
int iINF = (int) 1e20;
ll mod = (ll) 1e9 + 7;

void calc(ll v, vector<vector<ll>> &nodes, ll not_to_go, vector<bool> &used) {
    used[v] = true;
    for (auto i : nodes[v]) {
        if (!used[i] && i != not_to_go) {
            calc(i, nodes, not_to_go, used);
        }
    }
}

signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    ll t;
    cin >> t;
    while (t--) {
        ll n, m, a, b;
        cin >> n >> m >> a >> b;
        --a, --b;
        vector<vector<ll>> nodes(n);
        for (int i = 0; i < m; ++i) {
            ll u, v;
            cin >> u >> v;
            nodes[u - 1].push_back(v - 1);
            nodes[v - 1].push_back(u - 1);
        }
        vector<bool> usd1(n, false), usd2(n, false);
        calc(a, nodes, b, usd1);
        calc(b, nodes, a, usd2);
        ll nm1 = -1, nm2 = -1;
        for(auto i : usd1) {
            nm1 += (i == false);
//            cout << i << ' ';
        }
//        cout << '\n';
        for(auto i : usd2) {
            nm2 += (i == false);
        }
        cout << nm1 * nm2 << '\n';
    }
}


#include<bits/stdc++.h>
#define int long long
#define ll long long
#define ull unsigned long long
#define ff first
#define ss second
#define pb push_back
#define mk make_pair
#define ld long double
#define y1 asdfghjkl
#define ufo ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;

mt19937_64 mt_rnd_64(chrono::steady_clock::now().time_since_epoch().count());
long long rnd(long long l, long long r){
    return (mt_rnd_64() % (r-l+1)) + l;
}

const int N = 2 * 1e5 + 5;

int q;
int n,m,a,b,u,v,cnt,X,Y;
bool f1,f2;
vector<int>g[N];
int tin[N];
int tout[N];
int fup[N];
bool used[N];
int timer;
vector<int>c[N];
bool w[N];
bool ww[N];

void dfs(int v,int p,int call)
{
    used[v] = 1;
    tin[v] = fup[v] = ++timer;
    for(int i = 0;i < g[v].size();i++){
        int to = g[v][i];
        if(used[to])fup[v] = min(fup[v],tin[to]);
        else{
            call++;
            dfs(to,v,call);
            fup[v] = min(fup[v],fup[to]);
            if(fup[to] >= tin[v]){
                if(call > 1){
                    if(v == a || v == b)cnt++;
                }
            }
        }
    }
}

void dfs2(int v)
{
    used[v] = 1;
    c[timer].pb(v);
    for(int i = 0;i < g[v].size();i++){
        int to = g[v][i];
        if(!used[to])
            dfs2(to);
    }
}

main()
{
    ufo;
    cin>>q;
    for(int Q = 0;Q < q;Q++){
        cin>>n>>m>>a>>b;
        map<pair<int,int>,bool >mp;
        for(int i = 1;i <= n;i++){
            c[i].clear();
            g[i].clear();
            tin[i] = 0;
            tout[i] = 0;
            fup[i] = 0;
            used[i] = 0;
            w[i] = 0;
            ww[i] = 0;
        }
        for(int i = 0;i < m;i++){
            cin>>u>>v;
            if(mp.count(mk(u,v)))continue;;
            g[u].pb(v);
            g[v].pb(u);
            mp[mk(u,v)] = 1;
            mp[mk(v,u)] = 1;
        }
        cnt = 0;
        for(int i = 1;i <= n;i++)
            if(!used[i])
                dfs(i,-1,0);
        if(cnt < 2){
            cout<<0<<'\n';
            continue;
        }
        for(int i = 0;i < g[a].size();i++)w[g[a][i]]=1;
        for(int i = 0;i < g[b].size();i++)ww[g[b][i]]=1;
        for(int i = 1;i <= n;i++)used[i] = 0;
        used[a] = 1;
        used[b] = 1;
        timer = 0;
        for(int i = 1;i <= n;i++){
            if(!used[i]){
                timer++;
                dfs2(i);
            }
        }
        X = 0;
        Y = 0;
        for(int i = 1;i <= timer;i++){
            f1=0;
            f2=0;
            for(int j = 0;j < c[i].size();j++){
                v = c[i][j];
                if(w[v])f1 = 1;
                if(ww[v])f2 = 1;
            }
            if(f1 == f2)continue;
            if(f1)X += c[i].size();
            if(f2)Y += c[i].size();
        }
        cout<<X*Y<<'\n';
    }
}
/**
1
7 9 1 2
1 2
2 3
3 5
5 2
1 6
1 7
1 4
6 2
3 6

7
4 3 2 1
1 2
2 3
4 1
7 7 3 5
1 2
2 3
3 4
4 5
5 6
6 7
7 5
7 7 3 5
1 2
2 3
3 4
4 5
5 6
6 7
7 5
7 7 3 5
1 2
2 3
3 4
4 5
5 6
6 7
7 5
4 3 2 1
1 2
2 3
4 1
7 7 3 5
1 2
2 3
3 4
4 5
5 6
6 7
7 5
4 3 2 1
1 2
2 3
4 1

1
4 3 2 1
1 2
2 3
4 1
**/


#define _CRT_SECURE_NO_WARNINGS
#define pb push_back

#include <iostream>
#include <climits>
#include <algorithm>
#include <iomanip>
#include <cmath>
#include <vector>
#include <map>
#include <string>
#include <stack>
#include <set>
#include <cstdio>
#include <cctype>
#include <queue>
#include <bitset>
#include <functional>
#include <cassert>
#include <unordered_map>
#include <unordered_set>

using namespace std;

#define int long long

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef long double ld;
typedef double db;

const ll N = 1e6 + 20;
const ll INF = INT_MAX;

/*int p = 3571;
int mod = 2147483647;

namespace op {
	void add(int &a, int val) {
		a = ((a * p % mod + val) % mod + mod) % mod;
	}
	int calc(int a, int b) {
		return ((a % mod + b % mod) % mod + mod) % mod;
	}
	int mul(int a, int b) {
		return (((a % mod) * (b % mod)) % mod + mod) % mod;
	}
	int pow(int a, int n) {
		if (n == 0) return 1LL;
		if (n & 1) {
			int b = pow(a, n ^ 1) % mod;
			return mul(a, b);
		}
		else {
			int b = pow(a, n >> 1) % mod;
			return mul(b, b);
		}
	}
};
using namespace op;

struct hsh {
	string vec;
	vector<int> seg;
	int n;
	hsh(string a) {
		n = a.size();
		vec = a;
		seg.resize(a.size() + 1);
		for (int i = 0; i < a.size(); ++i) {
			seg[i + 1] = seg[i];
			add(seg[i + 1], a[i]);
		}
	}
	int seg_hash(int l, int r) {
		return calc(seg[r], (-1) * seg[l - 1] * pow(p, r - l + 1));
	}
};*/

vector<int> g[N];
int used[N], ct[N];

vector<int> comp[2];

int id;
void dfs(ll v) {
	comp[id].push_back(v);
	used[v] = 1;

	for (ll to : g[v]) {
		if (!used[to])
			dfs(to);
	}
}

void clear(int n) {
	for (ll i = 0; i < n; ++i) {
		g[i].clear();
		used[i] = ct[i] = 0;
	}
	comp[0].clear();
	comp[1].clear();
}

signed main() {
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
#else
#endif
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	int t;
	cin >> t;
	while (t--) {
		int n, m, a, b;
		cin >> n >> m >> a >> b;
		a--; b--;
		for (int i = 0; i < m; ++i) {
			int x, y;
			cin >> x >> y;
			--x; --y;
			g[x].push_back(y);
			g[y].push_back(x);
		}

		id = 0; used[b] = 1;
		dfs(a);
		for (auto &x : comp[0]) {
			used[x] = 0;
		}
		used[b] = 0;
		id = 1; used[a] = 1;
		dfs(b);
		for (auto &x : comp[0])
			ct[x]++;
		for (auto &x : comp[1])
			ct[x]++;

		int arr[2] = { -1,-1 };
		for (int i = 0; i < 2; ++i)
			for (auto &x : comp[i])
				if (ct[x] == 1)
					arr[i]++;

		cout << max(0ll, arr[0] * arr[1]) << endl;
		clear(n);
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;

vector<vector<int>> g;
vector<bool> used;
int coun = 0;
void dfs(int v, int nun){
    used[v] = 1;
    coun++;
    for (auto u : g[v]){
        if (used[u]) continue;
        if (u == nun) continue;
        dfs(u, nun);
    }
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    for (int i = 1; i <= t; i++){
        int n, m, a, b;
        cin >> n >> m >> a >> b;
        g.clear();
        used.clear();
        g.resize(n + 1);
        used.resize(n + 1);
        for (int j = 1; j <= m; j++){
            int l, r;
            cin >> l >> r;
            g[l].push_back(r);
            g[r].push_back(l);
        }

        dfs(a, b);
        coun = 0;
        dfs(b, 0);
        int c1 = coun - 1; coun = 0;

        used.clear();
        used.resize(n + 1);
        swap(a, b);

        dfs(a, b);
        coun = 0;
        dfs(b, 0);
        int c2 = coun - 1; coun = 0;

        cout << (long long)c1 * c2 << "\n";
    }
    return 0;
}


#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#define int long long

using namespace std;

const int MAXN = 200005;

vector<int> g[MAXN];
set<int> cpt;
bool used[MAXN];
int timer=1, tin[MAXN], fup[MAXN];

void dfs (int v, int p = -1) {
	used[v] = true;
	tin[v] = fup[v] = timer++;
	int children = 0, cut = 0;
	for (auto to : g[v]) {
		if (!used[to]) {
            children++;
            dfs(to, v);
            fup[v] = min(fup[to], fup[v]);
            if ((v == 0 && children > 1 || v != 0 && fup[to] >= tin[v]) && !cut++) cpt.insert(v);
		}
		else fup[v] = min(tin[to], fup[v]);
	}
}

bool found = 0;
int a, b, sz = 0;

void dfs2(int v){
    if(v == b) found = 1;
    used[v] = 1;
    sz++;
    for(auto u : g[v]){
        if(!used[u] && u != a) dfs2(u);

    }
}

void dfs3(int v){
    if(v == a) found = 1;
    used[v] = 1;
    sz++;
    for(auto u : g[v]){
        if(!used[u] && u != b) dfs3(u);

    }
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
	int n;
	int t; cin >> t;
	while(t--){
        int n, m;
        cin >> n >> m >> a >> b; a--, b--;
        memset(tin, 0, 8 * (n + 1));
        memset(fup, 0, 8 * (n + 1));
        for(int i = 0; i < n; ++i) g[i].clear();
        memset(used, 0, sizeof(bool) * (n + 1));
        cpt.clear();
        timer = 1;
        while(m--){
            int u, v; cin >> u >> v; u--, v--;
            g[u].push_back(v);
            g[v].push_back(u);
        }
        dfs(0);
        if(cpt.find(a) == cpt.end() || cpt.find(b) == cpt.end()){cout << "0\n"; continue;}
        memset(used, 0, sizeof(bool) * (n + 1));
        int sz1 = 0;
        for(int i = 0; i < g[a].size(); ++i){
            found = 0, sz = 0;
            if(!used[g[a][i]]){
                dfs2(g[a][i]);
                if(!found) sz1 += sz;
            }
        }
        //cout << sz1 << '\n';
        memset(used, 0, sizeof(bool) * (n + 1));
        int sz2 = 0;
        for(int i = 0; i < g[b].size(); ++i){
            found = 0, sz = 0;
            if(!used[g[b][i]]){
                dfs3(g[b][i]);
                if(!found) sz2 += sz;
            }
        }
        //cout << sz2 << '\n';
        cout << 1ll * sz1 * sz2 << '\n';
	}
}


/*
               _____
              /     \
              vvvvvvv  /|__/|
                 I   /O,O   |
                 I /_____   |      /|/|
                J|/^ ^ ^ \  |    /00  |    _//|
                 |^ ^ ^ ^ |W|   |/^^\ |   /oo |
                  \m___m__|_|    \m_m_|   \mm_|

 */
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#include <array>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>

#define fori(a, r) for(long long int a = 0; a < (r); ++a)
#define forI(a, r) for(long long int a = 1; a <= (r); ++a)

#define ff first
#define ss second
#define pll pair<ll, ll>

//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,tune=native")
//#pragma GCC optimize("fast-math")
//#pragma GCC optimize("unroll-loops")

using namespace std;
typedef long long int ll;
typedef long double ld;
typedef long long ull;

#define pt pair<ll, ll>
#define x first
#define y second

pt dxy[] = {{1,  0},
            {0,  1},
            {-1, 0},
            {0,  -1}};
ll months[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const long long MAXN = 300 * 1000 + 100, MOD = 1000000007, INF = 4LL * 1000 * 1000 * 1000 * 1000;

//mt19937 random(time(0));

ll n, m, a, b;

vector<ll> g[200 * 1000 + 1];
bool used[200 * 1000 + 1];

ll c;
ll e;

void dfs(ll v){
    used[v] = true;
    ++c;

    for(ll to: g[v]){
        if(to == a) e |= 1;
        else if(to == b) e |= 2;
        else if(!used[to]) dfs(to);
    }
}

void solve() {
    ll t;
    cin >> t;
    string s;

    fori(iuasfhgb, t) {
        ll x, y;
        cin >> n >> m >> a >> b;
        forI(i, n) used[i] = false;
        forI(i, n) g[i].clear();
        fori(i, m){
            cin >> x >> y;
            g[x].push_back(y);
            g[y].push_back(x);
        }

        ll A = 0, B = 0;
        bool ok = false;

        forI(i, n){
            if(!used[i] && i != a && i != b){
                c = 0, e = 0;
                dfs(i);
                if(e == 1) A += c;
                else if(e == 2) B += c;
            }
        }

        cout << A * B << "\n";
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
#define DEBUG0
#ifdef DEBUG
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#endif
    solve();
}


#include <bits/stdc++.h>

using namespace std;
const int N = (int)(2e5 + 123);

vector <int> g[N];
int was[N];
bool q;
int dfs(int v , int bad) {
	was[v] = true;
	int val = 1;
     for (auto to : g[v]) {
          if (to == bad) {
               q = false;
               continue;
          }
          if (was[to]) continue;
          val += dfs(to , bad);
     }
     return val;
}
vector <long long> aa , bb;
int main() {
	int t;
	cin >> t;
	while (t--) {
		int n , m , a , b;
		cin >> n >> m >> a >> b;

		aa.clear();
		bb.clear();
		for (int i=1; i<=n; i++) g[i].clear();
		for (int i=1; i<=n; i++) was[i] = 0;

		for (int i=1; i<=m; i++) {
			int u , v;
			cin >> u >> v;
			g[u].push_back(v);
			g[v].push_back(u);
		}
		was[a] = was[b] = true;
		for (auto to: g[a]) {
		     if (was[to] == false) {
		          q = true;
		          aa.push_back(dfs(to , b) * q);
		     }
		}
		for (auto to: g[b]) {
		     if (was[to] == false) {
		          q = true;
		          bb.push_back(dfs(to , a) * q);
		     }
		}

		/*for (int i=0; i<aa.size(); i++)
		     cout <<aa[i]<<" ";
		cout <<endl;
		for (int i=0; i<bb.size(); i++)
		     cout <<bb[i]<<" ";
		cout <<endl;*/

          long long ans = 0;
		for (int i=0; i<aa.size(); i++)
		     for (int j=0; j<bb.size(); j++)
		          ans += aa[i] * bb[j];
		cout <<ans<<endl;
	}
}


//#include "pch.h"
#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <algorithm>

using namespace std;

vector<vector<int> > graph;
vector<int> used;
vector<vector<int> > kol;

int st, ed;

void dfs1(int u) {
	used[u] = 1;
	kol[u].push_back(1);
	for (auto i : graph[u]) {
		if (used[i] == -1 and i!=ed) {
			dfs1(i);
		}
	}
}

void dfs2(int u) {
	used[u] = 1;
	kol[u].push_back(2);
	for (auto i : graph[u]) {
		if (used[i] == -1 and i!=st) {
			dfs2(i);
		}
	}
}

int main()
{
	ios_base::sync_with_stdio(false);
	int t = 0, n, m;
	cin >> t;
	for (int w = 0; w < t; w++) {
		cin >> n;
		long long left = 0, right = 0;
		cin >> m >> st >> ed;
		st--, ed--;
		graph = vector<vector<int> >(n);
		used = vector<int>(n, -1);
		kol = vector<vector<int> >(n);
		for (int i = 0; i < m; i++) {
			cin >> left >> right;
			left--, right--;
			graph[left].push_back(right);
			graph[right].push_back(left);
		}
		left = 0, right = 0;
		dfs1(st);
		used.assign(n, -1);
		dfs2(ed);
		for (int i = 0; i < n; i++) {
			if (kol[i].size() == 1) {
				if (kol[i][0] == 1) {
					left++;
				}
				else {
					right++;
				}
			}
		}
		cout << max(0ll, max(0ll, left - 1)*max(0ll, right - 1)) << "\n";
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
int a,b,n,m,us[200000],ans[3],q,x,y;
vector<int>V[200000];
void f1(int arc,int lol){
    if(us[arc] == lol){
        ans[us[arc]]--;
        us[arc]++;
        ans[us[arc]]++;
    }
    for(auto ar:V[arc]){
        if(us[ar] == lol && ar!=a && ar!=b){
            f1(ar,lol);
        }
    }
}
int main() {
    cin>>q;
    for(int ij=0;ij<q;ij++){
        cin>>n>>m>>a>>b;
        ans[0]=n;ans[1]=ans[2]=0;
        a--;
        b--;
        for(int i=0;i<n;i++){
            V[i].clear();
            us[i]=0;
        }
        for(int i=0;i<m;i++){
            cin>>x>>y;
            V[y-1].push_back(x-1);
            V[x-1].push_back(y-1);
        }
        f1(a,0);
        f1(b,1);
        cout<<(long long)(ans[0]-1)*(ans[1]-1)<<endl;
    }
}


//#define _GLIBCXX_DEBUG

#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES

#include <bits\stdc++.h>

using namespace std;

#define sz(x) ((long long)(x).size())
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()

typedef long long ll;

const ll inf = 1e18;

ll bin_pow(ll a, ll n) {
	if (n == 0)
		return 1;

	if (n % 2 == 0) {
		ll b = bin_pow(a, n / 2);
		return b * b;
	}
	else return a * bin_pow(a, n - 1);
}

vector<vector<ll>> g;
vector<bool> used;

ll flaga = false, flagb = false;
vector<ll> buf;

void dfs(ll v, ll a, ll b) {
	used[v] = true;
	buf.push_back(v);

	for (auto to : g[v]) {
		if (to == a)
			flaga = true;
		else if (to == b)
			flagb = true;
		else if (!used[to])
			dfs(to, a, b);
	}
}

int main() {
	ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);

	ll t; cin >> t;
	while (t--) {
		ll n, m, a, b; cin >> n >> m >> a >> b;
		g.clear();

		a--; b--;
		g.resize(n);
		used.assign(n, false);

		for (ll i = 0; i < m; i++) {
			ll u, v; cin >> u >> v;
			u--; v--;
			g[u].push_back(v);
			g[v].push_back(u);
		}

		vector<vector<ll>> ca, cb;

		for (ll i = 0; i < n; i++) {
			if (i != a && i != b && !used[i]) {
				flaga = false, flagb = false;
				buf.clear();

				dfs(i, a, b);

				if (flaga != flagb) {
					if (flaga) {
						ca.push_back(buf);
					}

					if (flagb) {
						cb.push_back(buf);
					}
				}
			}
		}

		ll mula = 0, mulb = 0;
		for (auto c : ca)
			mula += sz(c);
		for (auto c : cb)
			mulb += sz(c);

		ll ans = 0;
		for (auto c : ca) {
			ans += sz(c) * mulb;
		}
		for (auto c : cb) {
			ans += sz(c) * mula;
		}

		cout << ans / 2 << endl;
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <unordered_map>

using namespace std;

long long left = 0;

long long right = 0;

unordered_map<int, unordered_map<int, int>> gr;

void dfs(vector<int>& used, int now) {
    used[now] = 0;
    for (auto next : gr[now]) {
        if (next.second == 1 && used[next.first]) {
            dfs(used, next.first);
        }
    }
}

long long k = 0;

void dfs_(vector<int>& used, int now) {
    used[now] = 0;
    for (auto next : gr[now]) {
        if (next.second == 1 && used[next.first]) {
            dfs_(used, next.first);
        }
    }
    k++;
}

int main() {
    //freopen("input.txt", "r", stdin);
    int q;
    cin >> q;
    for (; q > 0; --q) {
        int n, m, a, b;
        cin >> n >> m >> a >> b;
        for (int i = 0; i < m; ++i) {
            int x, y;
            cin >> x >> y;
            gr[x][y] = 1;
            gr[y][x] = 1;
        }
        vector<int> used(n + 1, 1);
        vector<int> sos;
        for (auto now : gr[a]) {
            sos.push_back(now.first);
        }
        for (int i = 0; i < sos.size(); ++i) {
            gr[sos[i]][a] = 0;
            gr[a][sos[i]] = 0;
        }
        dfs(used, b);
        long long left = 0;
        for (int i = 0; i < sos.size(); ++i) {
            if (used[sos[i]] == 1) {
                dfs_(used, sos[i]);
                left += k;
                k = 0;
            }
        }
        for (int i = 0; i < sos.size(); ++i) {
            gr[sos[i]][a] = 1;
            gr[a][sos[i]] = 1;
        }
        used.assign(n + 1, 1);
        sos.clear();
        for (auto now : gr[b]) {
            sos.push_back(now.first);
        }
        for (int i = 0; i < sos.size(); ++i) {
            gr[sos[i]][b] = 0;
            gr[b][sos[i]] = 0;
        }
        dfs(used, a);
        long long right = 0;
        for (int i = 0; i < sos.size(); ++i) {
            if (used[sos[i]] == 1) {
                dfs_(used, sos[i]);
                right += k;
                k = 0;
            }
        }
        cout << left * right << "\n";
        gr.clear();
    }
    return 0;
}


#include "bits/stdc++.h"

#define fi first
#define se second
#define px first
#define py second
#define PB push_back

using namespace std;

typedef unsigned int UI;
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;

const int INF = 1e9 + 5;

//#define DEBUG
#ifdef DEBUG
#include "Debug.h"
#include "Debug2.h"
#endif

#ifndef DEBUG
//#define FILE_IO
#endif

vector<int> used;
bool key;
LL dfs(int v, int par, vector<vector<int>> &a, int p2) {
    if (v == p2) {
        key = true;
        return 1;
    }
    LL cnt = 0;
    used[v] = 1;
    for (auto u : a[v]) {
        if (u == par || used[u]) continue;
        cnt += dfs(u, v, a, p2);
    }
    return cnt + 1;
}

int main() {
#ifdef FILE_IO
    freopen("in.in", "r", stdin);
    freopen("out.out", "w", stdout);
#else
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
#endif
    int t;
    cin >> t;
    for (int qq = 0; qq < t; qq++) {
        int n, m;
        cin >> n >> m;
        used.assign(n, 0);
        int s, f;
        cin >> s >> f;
        s--;
        f--;
        vector<vector<int>> a(n);
        for (int i = 0; i < m; i++) {
            int x, y;
            cin >> x >> y;
            x--;
            y--;
            a[x].push_back(y);
            a[y].push_back(x);
        }
        LL ans1 = 0;
        for (auto i : a[s]) {
            if (used[i]) continue;
            key = false;
            used[s] = 1;
            LL t = dfs(i, s, a, f);
            if (!key) {
                ans1 += t;
            }
        }
        for (auto &i : used) i = 0;
        LL ans2 = 0;
        for (auto i : a[f]) {
            if (used[i]) continue;
            key = false;
            used[f] = 1;
            LL t = dfs(i, f, a, s);
            if (!key) {
                ans2 += t;
            }
        }
        cout << ans1 * ans2 << endl;
    }
    return 0;
}
/*
1
7 7 3 5
1 2
2 3
3 4
4 5
5 6
6 7
7 5
*/


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;

const int MAXN = 2e5;

vector<int> g[MAXN];
vector<bool> used1, used2;
set<int> s;

void dfs1(int v, int x) {
    used1[v] = true;
    for (auto &u : g[v]) {
        if (!used1[u] && u != x) {
            dfs1(u, x);
        }
    }
}

void dfs2(int v, int x) {
    used2[v] = true;
    for (auto &u : g[v]) {
        if (!used2[u] && u != x) {
            dfs2(u, x);
        }
    }
}

main() {
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#else
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
#endif
    int t;
    cin >> t;
    int prev = 0;
    while (t--) {
        for (int i = 0; i < prev; i++) {
            g[i].clear();
        }
        int n, m, a, b;
        cin >> n >> m >> a >> b;
        for (int i = 0; i < m; i++) {
            int v, u;
            cin >> v >> u;
            g[v - 1].emplace_back(u - 1);
            g[u - 1].emplace_back(v - 1);
        }
        prev = n;
        used1.assign(n, false);
        used2.assign(n, false);
        a--, b--;
        dfs1(a, b);
        dfs2(b, a);
        long long x = 0, y = 0;
        for (int i = 0; i < n; i++) {
            if (i == a || i == b) {
                continue;
            }
            if (used1[i]) {
                if (!used2[i]) {
                    x++;
                }
            } else if (used2[i]) {
                y++;
            }
        }
        cout << x * y << '\n';
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

const ll INF = 1e9 + 7;

void fast() {
	ios::sync_with_stdio(0);
	ios_base::sync_with_stdio(0);
	cout.tie(0);
	cin.tie(0);
}

istream& operator >> (istream& cin, vector<ll>& m1) {
    for (auto& el : m1) {
        cin >> el;
    }
    return cin;
}

ostream& operator << (ostream& cout, vector<ll>& m1)  {
    for (auto& el : m1) {
        cout << el << ' ';
    }
    return cout;
}

ll bin_pow(ll val, ll kol) {
    if (kol == 0) {
        return 1;
    }
    if (kol == 1) {
        return val;
    }
    if (kol & 1) {
        return val * bin_pow(val, kol - 1);
    }
    return bin_pow(val * val, kol / 2);
}

vector<ll> par;
vector<ll> sz;
vector<bool> usss;
vector<vector<int>> grf;

ll get(ll v)  {
    if (par[v] == v) {
        return v;
    }
    return (par[v] = get(par[v]));
}

void unite(ll v, ll u) {
    v = get(v);
    u = get(u);
    if (v == u) {
        return;
    }
    if (sz[u] > sz[v]) {
        swap(u, v);
    }
    par[u] = v;
    sz[v] += sz[u];
    return;
}

void dfs(int v, int check, bool& val) {
    usss[v] = true;
    if (v == check) {
        val = true;
        return;
    }
    for (auto& u : grf[v]) {
        if (usss[u]) {
            continue;
        }
        dfs(u, check, val);
    }
}

void solve() {
    ll n, m, a, b;
    cin >> n >> m >> a >> b;
    par.clear();
    sz.clear();
    grf.clear();
    usss.clear();
    usss.resize(n + 1, 0);
    grf.resize(n + 1);
    par.resize(n + 1);
    sz.resize(n + 1, 1);
    for (ll i = 0; i <= n; i++) {
        par[i] = i;
    }
    vector<pair<ll, ll>> m1, m2;
    for (ll i = 0; i < m; i++) {
        ll u, v;
        cin >> u >> v;
        grf[u].push_back(v);
        grf[v].push_back(u);
        if (u == a && v == b) {
            continue;
        }
        if (u == b && v == a) {
            continue;
        }
        if (u == a || v == a) {
            m1.push_back({u, v});
            continue;
        }
        if (u == b || v == b) {
            m2.push_back({u, v});
            continue;
        }
        unite(u, v);
    }
    vector<ll> used(n + 1, 0);
    for (auto& el : m1) {
        ll v;
        if (el.first == a) {
            v = get(el.second);
        }
        else {
            v = get(el.first);
        }
        used[v] = 1;
    }
    for (auto& el : m2) {
        ll v;
        if (el.second == b) {
            v = get(el.first);
        }
        else {
            v = get(el.second);
        }
        if (used[v] == 1) {
            used[v]++;
        }
    }
    ll val1 = 0;
    ll val2 = 0;
    vector<bool> is_count(n + 1, 0);
    for (auto& el : m1) {
        ll v;
        if (el.first == a) {
            v = get(el.second);
        }
        else {
            v = get(el.first);
        }
        if (used[v] != 2 && is_count[v] == 0) {
            val1 += sz[v];
            is_count[v] = 1;
        }
    }
    fill(is_count.begin(), is_count.end(), 0);
    for (auto& el : m2) {
        ll v;
        if (el.first == b) {
            v = get(el.second);
        }
        else {
            v = get(el.first);
        }
        if (used[v] != 2 && is_count[v] == 0) {
            val2 += sz[v];
            is_count[v] = 1;
        }
    }
    bool can = false;
    dfs(a, b, can);
    if (can == false) {
        cout << 0 << endl;
        return;
    }
    cout << val1 * val2 << endl;
}

signed main() {
	//ifstream cin("input.txt");
	//ofstream cout("output.txt");
	fast();

    ll n;
    cin >> n;
    for (ll i = 0; i < n; i++) {
        solve();
    }
    return 0;
}


// #define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <fstream>
#include <iomanip>
#include <numeric>
#include <sstream>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>
typedef long long ll;
const ll INF = 1e18;
const ll MOD = 998244353;
using namespace std;

ll calc;
int V;
void dfs1(const int v, const vector<vector<int>> &g, vector<bool> &used) {
	used[v] = true;
	for (auto &to : g[v])
		if (used[to] == 0 && to != V)
			dfs1(to, g, used);
	return;
}
void dfs2(const int v, const vector<vector<int>> &g, vector<bool> &used) {
	used[v] = true;
	++calc;
	for (auto &to : g[v])
		if (used[to] == 0)
			dfs2(to, g, used);
	return;
}

void solve(void) {
	int n, m, a, b;
	cin >> n >> m >> a >> b;
	--a;
	--b;
	vector<vector<int>> g(n);
	for (int i = 0; i < m; ++i) {
		int v1, v2;
		cin >> v1 >> v2;
		--v1;
		--v2;
		g[v1].push_back(v2);
		g[v2].push_back(v1);
	}

	vector<bool> used(n);
	V = a;
	calc = -1;
	dfs1(b, g, used);
	dfs2(a, g, used);
	ll fp = calc;

	used.assign(n, false);
	V = b;
	calc = -1;
	dfs1(a, g, used);
	dfs2(b, g, used);

	cout << fp * calc << '\n';
	return;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	int t;
	cin >> t;
	while (t--)
		solve();
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define pb push_back
#define mp make_pair
#define boost ios_base::sync_with_stdio(0); cin.tie(0);cout.tie(0)
#define f first
#define se second
#define lb lower_bound
#define ub upper_bound
#define pii pair<int, int>
#define all(x) x.begin(), x.end()

const int N = 2e5 + 144, mod = 1e9 + 7, inf = 1e9 + 7;
int n, m, a, b;
vector <int> g[N];
bool was[N];

ll bp(ll x, ll y){
    if(y == 0)
        return 1;
    if(y & 1)
        return (x * bp(x, y - 1));
    ll z = bp(x, y / 2);
    return (z * z) % mod;
}

void dfs(int x){
    was[x] = true;
    for(auto to: g[x])
        if(!was[to])
            dfs(to);
}

int main(){
    boost;
    int q;
    cin >> q;
    while(q--){
        cin >> n >> m >> a >> b;
        for(int i = 1; i <= m; i++){
            int x, y;
            cin >> x >> y;
            g[x].pb(y);
            g[y].pb(x);
        }
        ll x = 0, y = 0;
        was[b] = true;
        dfs(a);
        for(int i = 1; i <= n; i++){
            if(!was[i])
                x++;
            was[i] = 0;
        }
        was[a] = true;
        dfs(b);
        for(int i = 1; i <= n; i++){
            if(!was[i])
                y++;
            was[i] = 0;
        }
        for(int i = 1; i <= n; i++)
            g[i].clear();
        cout << x * y << "\n";
    }
    return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stdio.h>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

#define ft first
#define sd second
#define mp make_pair
#define all(x) x.begin(), x.end()
#define all_(x) x.rbegin(), x.rend()
#define multi_test 1
#define int ll

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;

const ll MAXN = 3e5 + 7;
const ll MOD = 1e9 + 7;
const ll MOD1 = 1e9 + 9;
const ll INF = 2e9 + 9;
const ld EPS = 1e-8;

void solve();

signed main() {
#ifdef _DEBUG
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int q = 1;
    if (multi_test) cin >> q;
    while (q--) solve();
}

/*-------------------------------------------------------------------------------------------------------------*/

int n, m, a, b, cnta = 0, cntb = 0;
vector<int> used;
vector<vector<int>> g;
bool checka, checkb;

int dfs(int v) {
    int res = 1;
    used[v] = true;
    for (int to : g[v]) {
        if (to == a)
            checka = true;
        if (to == b)
            checkb = true;
        if (!used[to] && to != a && to != b) {
            res += dfs(to);
        }
    }
    return res;
}

void solve() {
    cin >> n >> m >> a >> b;
    --a; --b;
    g.resize(n); used.resize(n);
    for (int i = 0; i < n; ++i) {
        g[i].clear();
        used[i] = 0;
    }
    cnta = cntb = 0;
    for (int i = 0; i < m; ++i) {
        int x, y;
        cin >> x >> y;
        --x; --y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for (int i = 0; i < n; ++i) {
        if (!used[i] && i != a && i != b) {
            checka = 0; checkb = 0;
            int r = dfs(i);
            if (checka && !checkb) {
                cnta += r;
            } else if (!checka && checkb) {
                cntb += r;
            }
        }
    }
    cout << cnta * cntb << '\n';
}


#include <bits/stdc++.h>

#define F first
#define S second
#define mp make_pair
#define pb push_back
#define sz(x) (int)x.size()

using namespace std;

const int N = (int)2e5 + 5;

int n,m,a,b;

long long A,B;

vector<int> g[N];

bool used[N],used1[N],used2[N],used3[N],used4[N];

void obnul(){
	A = 0;
	B = 0;
	for(int i = 1; i <= n; i++){
		g[i].clear();
		used[i] = false;
		used1[i] = false;
		used2[i] = false;
		used3[i] = false;
		used4[i] = false;
	}
}

void solve(){
	cin >> n >> m >> a >> b;
	for(int i = 1; i <= m; i++){
		int u,v;
		cin >> u >> v;
		g[u].pb(v);
		g[v].pb(u);
	}

	queue<int> q1,q2,q3,q4;
	q1.push(a);
	used1[a] = true;
	while(!q1.empty()){
		int v = q1.front();
		q1.pop();
	     if(v != b){
			for(auto to : g[v]){
				if(!used1[to]){
					q1.push(to);
					used1[to] = true;
				}
			}
	     }
	}
	q2.push(b);
	used2[b] = true;
	while(!q2.empty()){
		int v = q2.front();
		q2.pop();
		if(v != a){
			for(auto to : g[v]){
				if(!used2[to]){
					q2.push(to);
					used2[to] = true;
				}
			}
		}
	}
	for(int i = 1; i <= n; i++){
		if(used1[i] == true && used2[i] == true)
			used[i] = true;
	}

	q3.push(a);
	used3[a] = true;
	while(!q3.empty()){
		int v = q3.front();
		q3.pop();
		for(auto to : g[v]){
			if(!used[to] && !used3[to]){
				q3.push(to);
				used3[to] = true;
				A++;
			}
		}
	}

	q4.push(b);
	used4[b] = true;
	while(!q4.empty()){
		int v = q4.front();
		q4.pop();
		for(auto to : g[v]){
			if(!used[to] && !used4[to]){
				q4.push(to);
				used4[to] = true;
				B++;
			}
		}
	}
	cout << A * B << endl;
	obnul();
}

int main(){
   	ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
   	int tt;
   	cin >> tt;
   	while(tt--){
   		solve();
   	}
   	return 0;
}


#include <iostream>
#include <cstdio>

#include <functional>
#include <utility>
#include <cmath>
#include <algorithm>
#include <cassert>

#include <vector>
#include <set>
#include <queue>
#include <map>
#include <stack>
#include <unordered_map>

#include <string>
#include <iterator>
#include <iomanip>
#include <fstream>

#include <random>
#include <chrono>

using namespace std;

#define uint unsigned int
#define prll pair<ll,ll>
#define prdd pair<double,double>
#define m_p make_pair
#define INF (ll)1e18
#define ll long long

const ll q = 239017;
const ll mod = 1e9 + 7;
const ll mod2 = 1e9 + 13;
const ll MAXN = 2e5 + 100;
const ll MAXM = 4294967291;
const ll L = 26;

vector<ll> g[MAXN];
ll used[MAXN], ct[MAXN];

vector<ll> comp[2];

ll id;
void dfs(ll v)
{
	if (used[v])
		return;

	comp[id].push_back(v);

	used[v] = 1;

	for (ll to : g[v])
		dfs(to);
}

void foo()
{
	ll t; cin >> t;
	while (t--)
	{
		ll n, m, a, b; cin >> n >> m >> a >> b;
		--a; --b;

		for (ll i = 0; i < m; ++i)
		{
			ll u, v; cin >> u >> v;
			--u; --v;

			g[u].push_back(v);
			g[v].push_back(u);
		}

		id = 0; used[b] = 1;
		dfs(a);

		for (ll el : comp[0])
			used[el] = 0;

		used[b] = 0;

		id = 1; used[a] = 1;
		dfs(b);

		for (ll i = 0; i < 2; ++i)
			for (ll el : comp[i])
				++ct[el];

		ll mas[2] = { -1,-1 };
		for (ll i = 0; i < 2; ++i)
			for (ll el : comp[i])
				if (ct[el] == 1)
					++mas[i];

		cout << max(0ll, mas[0] * mas[1]) << '\n';

		for (ll i = 0; i < n; ++i)
		{
			g[i].clear();
			used[i] = ct[i] = 0;
		}
		comp[0].clear();
		comp[1].clear();
	}
}

int main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);

	foo();

	return 0;
}