Ikta has an extraordinary feeling for undirected graphs. Ikta likes the undirected graph G and its two-point s, t pair (G, s, t) that has the greatest "beauty". The "beauty" of a pair (G, s, t) is the edge e = \\ {u, v \\} (u and v are two different points of G), and the shortest path from s to t in G. Is the number of things whose length is greater than the length of the shortest path from s to t in the undirected graph with g plus e.

Your job is to write a program that seeks its "beauty" given a pair (G, s, t).



Input

The input is given in the following format.

> N M s t
> x1 y1
> ...
> xi yi
> ...
> xM yM
>

First, the number of vertices, the number of edges, and the integers N, M, s, t representing the two vertices of the undirected graph are input. From the 2nd line to the M + 1th line, two vertices connected by edges are input. (However, let the set of G vertices be \\ {1, ..., N \\}.)

Constraints

Each variable being input satisfies the following constraints.

* 2 ≤ N ≤ 100,000
* 1 ≤ M ≤ 300,000
* 1 ≤ s, t, xi, yi ≤ N
* Different from s and t
* Guaranteed to reach t from s

Output

When the given graph is G, output the "beauty" of the set (G, s, t) in one line.

Examples

Input

3 2 1 3
1 2
2 3


Output

1


Input

9 8 7 8
2 6
4 9
8 6
9 2
3 8
1 8
8 5
7 9


Output

7


Input

4 3 1 4
1 2
3 4
4 1


Output

0


Input

9 7 8 9
9 6
6 5
3 6
3 7
2 5
8 5
1 4


Output

2
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <functional>
#include <numeric>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <utility>
#include <sstream>
#include <complex>
#include <fstream>
#include <bitset>
#include <time.h>
#include <tuple>

using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;
typedef vector<ll> V;
typedef complex<double> Point;

#define PI acos(-1.0)
#define EPS 1e-10
const ll INF = 1e12;
const ll MOD = 1e9 + 7;

#define FOR(i,a,b) for(ll i=(a);i<(b);i++)
#define rep(i,N) for(ll i=0;i<(N);i++)
#define ALL(s) (s).begin(),(s).end()
#define EQ(a,b) (abs((a)-(b))<EPS)
#define EQV(a,b) ( EQ((a).real(), (b).real()) && EQ((a).imag(), (b).imag()) )
#define fi first
#define se second
#define N_SIZE (1LL << 20)
#define NIL -1
#define MAX_N 100100

ll sq(ll num) { return num*num; }
ll mod_pow(ll x, ll n) {
	if (n == 0)return 1;
	if (n == 1)return x%MOD;
	ll res = sq(mod_pow(x, n / 2));
	res %= MOD;
	if (n % 2 == 1) {
		res *= x;
		res %= MOD;
	}
	return res;
}
ll mod_add(ll a, ll b) { return (a + b) % MOD; }
ll mod_sub(ll a, ll b) { return (a - b + MOD) % MOD; }
ll mod_mul(ll a, ll b) { return a*b % MOD; }

class DK {
public:
	struct edge {
		int to;
		ll cost;
	};

	int prev[100010];
	ll d[100010];
	int N;
	vector<edge> G[100010];//各頂点からの辺

	void dijkstra(int start) {
		fill(d, d + 100010, INF);
		d[start] = 0;
		fill(prev, prev + 100010, -1);

		priority_queue<P, vector<P>, greater<P>> que;
		que.push(P(0, start));

		while (!que.empty()) {
			P p = que.top();
			que.pop();
			int v = p.second;
			if (d[v] < p.first)continue;
			for (int i = 0; i < G[v].size(); i++) {
				edge e = G[v][i];
				if (d[e.to] > d[v] + e.cost) {
					d[e.to] = d[v] + e.cost;
					prev[e.to] = v;
					que.push(P(d[e.to], e.to));
				}
			}
		}
	}

	vector<int> get_path(int goal) {
		vector<int> path;
		for (int t = goal; t != -1; t = prev[t]) {
			path.push_back(t);
		}//このままでは逆順なのでひっくり返す
		reverse(ALL(path));
		return path;
	}
};

int n, m, s, t;
DK dk;
ll cnt[2][200100] = {};
ll ans;

int main() {
	cin >> n >> m >> s >> t;
	s--;
	t--;
	rep(i, m) {
		int x, y;
		cin >> x >> y;
		x--; y--;
		dk.G[x].push_back({ y,1 });
		dk.G[y].push_back({ x,1 });
	}
	dk.dijkstra(s);
	rep(i, n) {
		if (dk.d[i] != INF)cnt[0][dk.d[i]]++;
	}
	dk.dijkstra(t);
	rep(i, n) {
		if (dk.d[i] != INF)cnt[1][dk.d[i]]++;
	}
	int now = 0;
	rep(i, dk.d[s] - 1) {
		//cout << cnt[0][i] << " " << cnt[1][dk.d[s] - 2 - i] << endl;
		ans += cnt[0][i] * cnt[1][dk.d[s] - 2 - i];
	}
	cout << ans << endl;
}
