#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 2000;
const int maxm = 1000 * 10;
struct edge {
  int v, w, next;
} e[maxm * 2];
struct node {
  int d, u;
  bool operator<(const node &b) const { return d > b.d; }
};
int head[maxn], d[maxn], d2[maxn];
int tot;
bool vis[maxn];
int g[maxn][maxn];
void add(int u, int v, int w) {
  e[tot].v = v;
  e[tot].w = w;
  e[tot].next = head[u];
  head[u] = tot++;
}
void dijkstra(int s, int t, int n, bool dir) {
  for (int i = 1; i <= n; i++) {
    if (dir)
      d[i] = INF;
    else
      d2[i] = INF;
  }
  if (dir)
    d[s] = 0;
  else
    d2[s] = 0;
  memset(vis, 0, sizeof(vis));
  priority_queue<node> q;
  q.push(node{0, s});
  while (!q.empty()) {
    node temp = q.top();
    q.pop();
    int u = temp.u;
    if (vis[u]) continue;
    vis[u] = 1;
    for (int i = head[u]; i != -1; i = e[i].next) {
      int v = e[i].v;
      int w = e[i].w;
      if (dir) {
        if (d[v] > d[u] + w) {
          d[v] = d[u] + w;
          q.push(node{d[v], v});
        }
      } else {
        if (d2[v] > d2[u] + w) {
          d2[v] = d2[u] + w;
          q.push(node{d2[v], v});
        }
      }
    }
  }
}
int main() {
  int n, m, s, t, u, v;
  cin >> n >> m >> s >> t;
  memset(head, -1, sizeof(head));
  for (int i = 0; i < m; i++) {
    cin >> u >> v;
    g[u][v] = 1;
    g[v][u] = 1;
    add(u, v, 1);
    add(v, u, 1);
  }
  dijkstra(s, t, n, true);
  dijkstra(t, s, n, false);
  long long ans = 0;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++)
      if (!g[i][j] && i != j) {
        if (d[i] + d2[j] + 1 >= d[t] && d2[i] + d[j] + 1 >= d[t]) {
          ans++;
          g[i][j] = g[j][i] = true;
        }
      }
  }
  cout << ans << endl;
}
