Little town Nsk consists of n junctions connected by m bidirectional roads. Each road connects two distinct junctions and no two roads connect the same pair of junctions. It is possible to get from any junction to any other junction by these roads. The distance between two junctions is equal to the minimum possible number of roads on a path between them.

In order to improve the transportation system, the city council asks mayor to build one new road. The problem is that the mayor has just bought a wonderful new car and he really enjoys a ride from his home, located near junction s to work located near junction t. Thus, he wants to build a new road in such a way that the distance between these two junctions won't decrease. 

You are assigned a task to compute the number of pairs of junctions that are not connected by the road, such that if the new road between these two junctions is built the distance between s and t won't decrease.

Input

The firt line of the input contains integers n, m, s and t (2 ≤ n ≤ 1000, 1 ≤ m ≤ 1000, 1 ≤ s, t ≤ n, s ≠ t) — the number of junctions and the number of roads in Nsk, as well as the indices of junctions where mayors home and work are located respectively. The i-th of the following m lines contains two integers ui and vi (1 ≤ ui, vi ≤ n, ui ≠ vi), meaning that this road connects junctions ui and vi directly. It is guaranteed that there is a path between any two junctions and no two roads connect the same pair of junctions.

Output

Print one integer — the number of pairs of junctions not connected by a direct road, such that building a road between these two junctions won't decrease the distance between junctions s and t.

Examples

Input

5 4 1 5
1 2
2 3
3 4
4 5


Output

0


Input

5 4 3 5
1 2
2 3
3 4
4 5


Output

5


Input

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


Output

3
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;

public class D {
	static long[] distOfS;
	static long[] distOfT;
	static long INF = 100000000000000000L;
	static ArrayList<ArrayList<Edge>> adj;
	
	static class Edge {
		int to;
		long w;
		Edge(int _to, long _w) {
			this.to = _to;
			this.w = _w;
		}
		
		@Override
		public String toString() {
			return "(to=" + to + ", w=" + w + ")";
		}
		
	}
	
	static class NextNode {
		int id;
		long cost;
		NextNode(int _id, long _cost) {
			id = _id; cost = _cost;
		}
	}
	
	static void initG(int V) { // V: the number of vertexes
		for(int i=0; i<V; i++) {
			adj.add(new ArrayList<Edge>());
		}
	}

	static void dijkstra(int s) {
		Arrays.fill(distOfS, INF);
		distOfS[s] = 0;
		PriorityQueue<NextNode> pq = new PriorityQueue<NextNode>(new Comparator<NextNode>() {
			public int compare(NextNode n1, NextNode n2) {
				if(n1.cost > n2.cost) return 1;
				else if(n1.cost==n2.cost) return 0;
				else return -1;
			}
		});
		pq.add(new NextNode(s, 0));
		while(!pq.isEmpty()) {
			NextNode cn = pq.poll();
			if(cn.cost > distOfS[cn.id]) continue;
			for(Edge e : adj.get(cn.id)) {
				if(cn.cost + e.w < distOfS[e.to]) {
					distOfS[e.to] = cn.cost + e.w;
					pq.add(new NextNode(e.to, distOfS[e.to]));
				}
			}
		}
	}
	static void dijkstra2(int s) {
		Arrays.fill(distOfT, INF);
		distOfT[s] = 0;
		PriorityQueue<NextNode> pq = new PriorityQueue<NextNode>(new Comparator<NextNode>() {
			public int compare(NextNode n1, NextNode n2) {
				if(n1.cost > n2.cost) return 1;
				else if(n1.cost==n2.cost) return 0;
				else return -1;
			}
		});
		pq.add(new NextNode(s, 0));
		while(!pq.isEmpty()) {
			NextNode cn = pq.poll();
			if(cn.cost > distOfT[cn.id]) continue;
			for(Edge e : adj.get(cn.id)) {
				if(cn.cost + e.w < distOfT[e.to]) {
					distOfT[e.to] = cn.cost + e.w;
					pq.add(new NextNode(e.to, distOfT[e.to]));
				}
			}
		}
	}

	public static void main(String[] args) throws IOException {
		MyScanner sc = new MyScanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int s = sc.nextInt();
		int t = sc.nextInt();
		boolean[][] exist = new boolean[n+1][n+1];
		distOfS = new long[n+1];
		distOfT = new long[n+1];
		adj = new ArrayList<ArrayList<Edge>>(n+1);
		initG(n+1);
		for(int i=0; i<m; i++) {
			int s1 = sc.nextInt();
			int t1 = sc.nextInt();
			adj.get(s1).add(new Edge(t1, 1));
			adj.get(t1).add(new Edge(s1, 1));
			exist[s1][t1]=true;
			exist[t1][s1]=true;
		}
		dijkstra(s);
		dijkstra2(t);
		int ans = 0;
		for(int from=1; from<=n; from++) {
			for(int to=from+1; to<=n; to++) {
				long tmp1 = distOfS[from]+1+distOfT[to];
				long tmp2 = distOfT[from]+1+distOfS[to];
				if(distOfS[t]>tmp1 || distOfS[t]>tmp2) {
					;
				} else {
					if(!exist[from][to]) ans++;
				}
			}
		}
		System.out.println(ans);
	}

	static class MyScanner
	{
		BufferedReader br;
		StringTokenizer st;
		public MyScanner(InputStream s)
		{
			br=new BufferedReader(new InputStreamReader(s));
		}
		public String nextLine() throws IOException
		{
			return br.readLine();
		}
		public String next() throws IOException
		{
			while(st==null || !st.hasMoreTokens())
				st=new StringTokenizer(br.readLine());
			return st.nextToken();
		}
		public int nextInt() throws IOException
		{
			return Integer.parseInt(next());
			
		}
		public double nextDouble() throws IOException
		{
			return Double.parseDouble(next());
		}
		public boolean ready() throws IOException
		{
			return br.ready();
		}
		public long nextLong() throws IOException
		{
			return Long.parseLong(next());
		}
	}
}