#include <bits/stdc++.h>
using namespace std;
const double DINF = numeric_limits<double>::infinity();
const long long MOD = 1e9 + 7;
const double EPS = 1e-7;
long long gcd(long long a, long long b) { return b ? gcd(b, a % b) : a; }
mt19937 mmtw(MOD);
long long rnd(long long x, long long y) {
  static uniform_int_distribution<long long> d;
  return d(mmtw) % (y - x + 1) + x;
}
template <class T>
T fact(T n) {
  if (n == 1) return 1;
  return n * fact(n - 1);
}
const int MAXN = 1005;
int n, m, second, first;
vector<int> g[MAXN];
bool e[MAXN][MAXN];
int d1[MAXN];
int d2[MAXN];
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m >> second >> first;
  second--;
  first--;
  for (int i = 0; i < m; ++i) {
    int p, q;
    cin >> p >> q;
    g[p - 1].push_back(q - 1);
    g[q - 1].push_back(p - 1);
    e[p - 1][q - 1] = true;
    e[q - 1][p - 1] = true;
  }
  fill(d1, d1 + n, INT_MAX);
  fill(d2, d2 + n, INT_MAX);
  queue<int> q;
  q.push(second);
  d1[second] = 0;
  while (!q.empty()) {
    int v = q.front();
    q.pop();
    for (auto to : g[v]) {
      if (d1[to] == INT_MAX) {
        d1[to] = d1[v] + 1;
        q.push(to);
      }
    }
  }
  q.push(first);
  d2[first] = 0;
  while (!q.empty()) {
    int v = q.front();
    q.pop();
    for (auto to : g[v]) {
      if (d2[to] == INT_MAX) {
        d2[to] = d2[v] + 1;
        q.push(to);
      }
    }
  }
  int res = 0;
  int sh = d1[first];
  for (int i = 0; i < n; ++i) {
    for (int j = i + 1; j < n; ++j) {
      if (e[i][j]) continue;
      if (d1[i] <= d1[j]) {
        if (d1[i] + 1 + d2[j] >= sh) {
          res++;
        }
      } else {
        if (d1[j] + 1 + d2[i] >= sh) {
          res++;
        }
      }
    }
  }
  cout << res << endl;
}
