#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1100;
const int MAXM = 2200;
const int inf = 0x3f3f3f3f;
bool maps[MAXN][MAXN];
struct edge_t {
  int v, next;
} edge[MAXM];
int tot;
int head[MAXN];
void init() {
  tot = 0;
  memset(head, -1, sizeof(head));
  memset(maps, false, sizeof(maps));
}
void addedge(int u, int v) {
  maps[u][v] = true;
  edge[tot].v = v;
  edge[tot].next = head[u];
  head[u] = tot++;
}
struct qnode {
  int v, c;
  qnode() {}
  qnode(int _v, int _c) : v(_v), c(_c) {}
  bool operator<(const qnode &r) const { return c > r.c; }
};
int dists[MAXN];
int distt[MAXN];
bool vis[MAXN];
void dijstra(int n, int start, int *dist) {
  memset(vis, false, sizeof(vis));
  for (int i = 1; i <= n; i++) dist[i] = inf;
  priority_queue<qnode> que;
  while (!que.empty()) que.pop();
  dist[start] = 0;
  que.push(qnode(start, 0));
  while (!que.empty()) {
    qnode temp = que.top();
    que.pop();
    int u = temp.v;
    if (vis[u]) continue;
    vis[u] = true;
    for (int i = head[u]; i != -1; i = edge[i].next) {
      int v = edge[i].v;
      if (!vis[v] && dist[v] > dist[u] + 1) {
        dist[v] = dist[u] + 1;
        que.push(qnode(v, dist[v]));
      }
    }
  }
}
int main() {
  int n, m, s, t;
  while (scanf("%d%d%d%d", &n, &m, &s, &t) != EOF) {
    init();
    for (int i = 1; i <= m; i++) {
      int u, v;
      scanf("%d%d", &u, &v);
      addedge(u, v);
      addedge(v, u);
    }
    dijstra(n, s, dists);
    dijstra(n, t, distt);
    int total = 0;
    for (int i = 1; i <= n; i++)
      for (int j = i + 1; j <= n; j++) {
        if (maps[i][j] || i == j) continue;
        int temp1 = dists[i] + 1 + distt[j];
        int temp2 = dists[j] + 1 + distt[i];
        int ori = dists[t];
        if (min(temp1, temp2) >= ori) total++;
      }
    printf("%d\n", total);
  }
  return 0;
}
