Problem:
イクタ君は、無向グラフについて異常なほどの思い入れを持っている。イクタ君は、無向グラフ G とその 2 点 s,tの組(G,s,t)のうち、その「うつくしさ」が大きいものが好きである。
組(G,s,t)の「うつくしさ」とは、辺 e = \{u, v\} (u と v は G の異なる 2 点) で、Gにおけるsからtへの最短路の長さが、Gにeをつけくわえた無向グラフにおけるsからtへの最短路の長さより 1 だけ大きいものの個数である。

あなたの仕事は、組(G,s,t)が与えられたとき、その「うつくしさ」を求めるプログラムを書くことである。

Input

入力は以下の形式で与えられる。

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

最初に無向グラフの頂点数、辺数、2つの頂点を表す整数N,M,s,tが入力される。
2行目からM+1行目までは辺によって結ばれている2つの頂点が入力される。
(ただし、G の頂点集合を\{1,..., N\}とする。)

Constraints

入力中の各変数は以下の制約を満たす。

2≤ N ≤ 100,000

1≤ M ≤ 300,000

1≤ s,t,xi,yi ≤ N

s と t とは異なる

s から t に辿り着けることは保証されている

Output

与えられたグラフをGとしたとき、組(G,s,t)の「うつくしさ」を1行で出力せよ。

Sample Input 1

3 2 1 3
1 2
2 3

Output for the Sample Input 1

1

頂点1から頂点3に辺を張ると、2点間の最短距離が 1 短くなる。

Sample Input 2

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

Output for the Sample Input 2

7

Sample Input 3

4 3 1 4
1 2
3 4
4 1

Output for the Sample Input 3

0

頂点1と頂点4には既に辺が張られているので、これ以上距離を縮めることはできない。

Sample Input 4

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

Output for the Sample Input 4

2

Solution in Rust (judge verdict: Accepted)

extern crate core;

use std::fmt;
use std::cmp::{max, min, Ordering};
use std::collections::{BinaryHeap, BTreeMap, VecDeque};
use std::fmt::{Display, Formatter, Error};
use std::ops::Range;
macro_rules! read_line{
    () => {{
        let mut line = String::new();
        std::io::stdin().read_line(&mut line).ok();
        line
    }};
    (delimiter: ' ') => {
        read_line!().split_whitespace().map(|x|x.to_string()).collect::<Vec<_>>()
    };
    (delimiter: $p:expr) => {
        read_line!().split($p).map(|x|x.to_string()).collect::<Vec<_>>()
    };
    (' ') => {
        read_line!(delimiter: ' ')
    };
    ($delimiter:expr) => {
        read_line!(delimiter: $delimiter)
    };
    (' '; $ty:ty) => {
        read_line!().split_whitespace().map(|x|x.parse::<$ty>().ok().unwrap()).collect::<Vec<$ty>>()
    };
    ($delimiter:expr; $ty:ty) => {
        read_line!($delimiter).into_iter().map(|x|x.parse::<$ty>().ok().unwrap()).collect::<Vec<$ty>>()
    };
}
macro_rules! let_all {
    ($($n:ident:$t:ty),*) => {
        let line = read_line!(delimiter: ' ');
        let mut iter = line.iter();
        $(let $n:$t = iter.next().unwrap().parse().ok().unwrap();)*
    };
}

struct ValueWithKey<K, V> {
    key: K, value: V,
}
impl <K, V> Ord for ValueWithKey<K, V> where K: Ord {
    fn cmp(&self, other: &Self) -> Ordering {
        self.key.cmp(&other.key)
    }
}
impl <K, V> PartialOrd for ValueWithKey<K, V> where K: PartialOrd {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.key.partial_cmp(&other.key)
    }
}
impl <K, V> PartialEq for ValueWithKey<K, V> where K: PartialEq {
    fn eq(&self, other: &Self) -> bool {
        self.key == other.key
    }
}
impl <K, V> Eq for ValueWithKey<K, V> where K: Eq {}

fn lower_bound<T>(array: &Vec<T>, target: &T) -> usize where T: Ord {
    let mut left = 0;
    let mut right = array.len();
    while left < right {
        let mid = (left + right) / 2;
        if array[mid] < *target {
            left = mid + 1;
        }else {
            right = mid;
        }
    }
    right
}
fn upper_bound<T>(array: &Vec<T>, target: &T) -> usize where T: Ord {
    let mut left = 0;
    let mut right = array.len();
    while left < right {
        let mid = (left + right) / 2;
        if array[mid] <= *target {
            left = mid + 1;
        }else {
            right = mid;
        }
    }
    right
}
fn main(){
    let_all!(n: usize, m: usize, s: usize, t: usize);
    let mut nodes = vec![Vec::<usize>::new(); n];
    for _ in 0 .. m {
        let_all!(x: usize, y: usize);
        nodes[x - 1].push(y - 1);
        nodes[y - 1].push(x - 1);
    }
    let mut queue = VecDeque::<usize>::new();
    let mut min_length_from_start = vec![-1; n];
    min_length_from_start[s - 1] = 0;
    queue.push_back(s -1);
    while let Some(c) = queue.pop_front() {
        for &n in &nodes[c] {
            if min_length_from_start[n] == -1 {
                min_length_from_start[n] = min_length_from_start[c] + 1;
                queue.push_back(n);
            }
        }
    }
    let mut min_length_from_goal = vec![-1; n];
    min_length_from_goal[t - 1] = 0;
    queue.push_back(t - 1);
    while let Some(c) = queue.pop_front() {
        for &n in &nodes[c] {
            if min_length_from_goal[n] == -1 {
                min_length_from_goal[n] = min_length_from_goal[c] + 1;
                queue.push_back(n);
            }
        }
    }
    min_length_from_goal.sort();
    let target_length = min_length_from_start[t - 1] - 1;
    let mut result = 0;
    for &from_start in &min_length_from_start {
        if target_length > from_start && from_start >= 0 {
            result += upper_bound(&min_length_from_goal, &(target_length - from_start - 1)) - lower_bound(&min_length_from_goal, &(target_length - from_start - 1));
        }
    }
    println!("{}", result);
}