Problem:
Score : 500 points

Problem Statement

There are N towns numbered 1 to N and M roads. The i-th road connects Town A_i and Town B_i bidirectionally and has a length of C_i.

Takahashi will travel between these towns by car, passing through these roads. The fuel tank of his car can contain at most L liters of fuel, and one liter of fuel is consumed for each unit distance traveled. When visiting a town while traveling, he can full the tank (or choose not to do so). Travel that results in the tank becoming empty halfway on the road cannot be done.

Process the following Q queries:

The tank is now full. Find the minimum number of times he needs to full his tank while traveling from Town s_i to Town t_i. If Town t_i is unreachable, print -1.

Constraints

All values in input are integers.

2 \leq N \leq 300

0 \leq M \leq \frac{N(N-1)}{2}

1 \leq L \leq 10^9

1 \leq A_i, B_i \leq N

A_i \neq B_i

\left(A_i, B_i\right) \neq \left(A_j, B_j\right) (if i \neq j)

\left(A_i, B_i\right) \neq \left(B_j, A_j\right) (if i \neq j)

1 \leq C_i \leq 10^9

1 \leq Q \leq N\left(N-1\right)

1 \leq s_i, t_i \leq N

s_i \neq t_i

\left(s_i, t_i\right) \neq \left(s_j, t_j\right) (if i \neq j)

Input

Input is given from Standard Input in the following format:

N M L
A_1 B_1 C_1
:
A_M B_M C_M
Q
s_1 t_1
:
s_Q t_Q

Output

Print Q lines.

The i-th line should contain the minimum number of times the tank needs to be fulled while traveling from Town s_i to Town t_i. If Town t_i is unreachable, the line should contain -1 instead.

Sample Input 1

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

Sample Output 1

0
1

To travel from Town 3 to Town 2, we can use the second road to reach Town 2 without fueling the tank on the way.

To travel from Town 1 to Town 3, we can first use the first road to get to Town 2, full the tank, and use the second road to reach Town 3.

Sample Input 2

4 0 1
1
2 1

Sample Output 2

-1

There may be no road at all.

Sample Input 3

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

Sample Output 3

0
0
1
2
0
0
1
2
0
0
0
1
1
1
0
0
2
2
1
0

Solution in Rust (1.15.1) (judge verdict: Time Limit Exceeded)

#![allow(unused_macros, deprecated)]

#[allow(dead_code)]
mod utils {
    use std::io::{
        self, BufRead, BufReader, BufWriter, Seek, SeekFrom, Stdin, StdinLock, Stdout, StdoutLock,
        Write,
    };
    use std::mem;
    use std::ops::{Deref, DerefMut};
    use std::ptr;
    use std::slice;
    use std::str::{self, FromStr};

    #[inline]
    fn is_space_or_line_break(b: &u8) -> bool {
        *b == b' ' || *b == b'\n'
    }

    pub struct Scanner<R: BufRead> {
        reader: R,
        buf: Vec<u8>,
    }

    impl<R: BufRead> Scanner<R> {
        #[inline]
        pub fn new(reader: R) -> Scanner<R> {
            Scanner {
                reader: reader,
                buf: Vec::with_capacity(100),
            }
        }

        pub fn read<T: FromStr>(&mut self) -> T {
            self.read_until(is_space_or_line_break);
            self.parse()
        }

        pub fn read2<T1: FromStr, T2: FromStr>(&mut self) -> (T1, T2) {
            (self.read(), self.read())
        }

        pub fn read3<T1: FromStr, T2: FromStr, T3: FromStr>(&mut self) -> (T1, T2, T3) {
            (self.read(), self.read(), self.read())
        }

        pub fn read4<T1: FromStr, T2: FromStr, T3: FromStr, T4: FromStr>(
            &mut self,
        ) -> (T1, T2, T3, T4) {
            (self.read(), self.read(), self.read(), self.read())
        }

        pub fn reads(&mut self) -> &str {
            self.read_until(is_space_or_line_break);
            unsafe { str::from_utf8_unchecked(&self.buf) }
        }

        pub fn readl(&mut self) -> &str {
            self.buf.clear();
            self.reader.read_until(b'\n', &mut self.buf).unwrap();
            let bytes = if self.buf.last() == Some(&b'\n') {
                &self.buf[..self.buf.len() - 1]
            } else {
                &self.buf
            };
            unsafe { str::from_utf8_unchecked(&bytes) }
        }

        pub fn read_vec<T: FromStr>(&mut self, count: usize) -> Vec<T> {
            (0..count).map(|_| self.read()).collect()
        }

        fn read_until<P: FnMut(&u8) -> bool>(&mut self, mut predicate: P) {
            self.buf.clear();
            let mut first = true;

            // https://doc.rust-lang.org/src/std/io/mod.rs.html#1623-1649
            loop {
                let (done, used) = {
                    let available = self.reader.fill_buf().unwrap();
                    if first && available.len() == 0 {
                        panic!("Scan Error (EOF reached)");
                    }

                    match available.iter().position(&mut predicate) {
                        Some(0) if first => (false, 1),
                        Some(i) => {
                            self.buf.extend_from_slice(&available[..i]);
                            (true, i + 1)
                        }
                        None => {
                            self.buf.extend_from_slice(available);
                            (false, available.len())
                        }
                    }
                };

                self.reader.consume(used);
                if done || used == 0 {
                    return;
                }

                first = false;
            }
        }

        #[inline]
        fn parse<T: FromStr>(&mut self) -> T {
            // 文字列をT型へパースする
            let elem = unsafe { str::from_utf8_unchecked(&self.buf) };
            elem.parse()
                .unwrap_or_else(|_| panic!(format!("failed parsing: {}", elem)))
        }
    }

    impl<R: BufRead + Seek> Seek for Scanner<R> {
        #[inline]
        fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
            self.reader.seek(pos)
        }
    }

    pub struct StdinScanner {
        stdin: Stdin,
        scanner: Scanner<BufReader<StdinLock<'static>>>,
    }

    impl StdinScanner {
        #[inline]
        pub fn new() -> StdinScanner {
            let stdin = io::stdin();
            let stdinlock = unsafe { mem::transmute(stdin.lock()) };
            let reader = BufReader::with_capacity(4096, stdinlock);
            let scanner = Scanner::new(reader);
            StdinScanner {
                stdin: stdin,
                scanner: scanner,
            }
        }
    }

    impl Deref for StdinScanner {
        type Target = Scanner<BufReader<StdinLock<'static>>>;

        #[inline]
        fn deref(&self) -> &Self::Target {
            &self.scanner
        }
    }

    impl DerefMut for StdinScanner {
        #[inline]
        fn deref_mut(&mut self) -> &mut Self::Target {
            &mut self.scanner
        }
    }

    pub struct StdoutWriter {
        stdout: Stdout,
        writer: BufWriter<StdoutLock<'static>>,
    }

    impl StdoutWriter {
        #[inline]
        pub fn new() -> StdoutWriter {
            let stdout = io::stdout();
            let stdoutlock = unsafe { mem::transmute(stdout.lock()) };
            let writer = BufWriter::with_capacity(4096, stdoutlock);
            StdoutWriter {
                stdout: stdout,
                writer: writer,
            }
        }

        pub fn write<T: Writable>(&mut self, v: T) {
            v.display(&mut self.writer);
        }

        pub fn writeln<T: Writable>(&mut self, v: T) {
            v.display(&mut self.writer);
            self.writer.write_all(b"\n").unwrap();
        }

        pub fn write_horizontal<I>(&mut self, iter: I)
        where
            I: IntoIterator,
            I::Item: Writable,
        {
            let mut it = iter.into_iter();
            if let Some(elem) = it.next() {
                elem.display(&mut self.writer);
            } else {
                return;
            }

            for elem in it {
                elem.display(&mut self.writer);
                self.writer.write_all(b" ").unwrap();
            }
        }

        pub fn write_vertical<I>(&mut self, iter: I)
        where
            I: IntoIterator,
            I::Item: Writable,
        {
            let mut it = iter.into_iter();
            if let Some(elem) = it.next() {
                elem.display(&mut self.writer);
            } else {
                return;
            }

            for elem in it {
                elem.display(&mut self.writer);
                self.writer.write_all(b"\n").unwrap();
            }
        }
    }

    impl Write for StdoutWriter {
        #[inline]
        fn flush(&mut self) -> io::Result<()> {
            self.writer.flush()
        }

        #[inline]
        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
            self.writer.write(buf)
        }
    }

    static DEC_DIGITS_LUT: &'static [u8; 200] = b"0001020304050607080910111213141516171819\
            2021222324252627282930313233343536373839\
            4041424344454647484950515253545556575859\
            6061626364656667686970717273747576777879\
            8081828384858687888990919293949596979899";

    fn write_int<W: Write>(mut writer: W, mut n: u64, is_negative: bool) {
        unsafe {
            let mut buf: [u8; 39] = mem::uninitialized();
            let buf_ptr_start = buf.as_mut_ptr().offset(39);
            let mut buf_ptr = buf_ptr_start;
            let lut_ptr = DEC_DIGITS_LUT.as_ptr();

            while n >= 10000 {
                let rem = (n % 10000) as isize;
                n /= 10000;

                let d1 = (rem / 100) << 1;
                let d2 = (rem % 100) << 1;
                buf_ptr = buf_ptr.offset(-4);
                ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr, 2);
                ptr::copy_nonoverlapping(lut_ptr.offset(d2), buf_ptr.offset(2), 2);
            }

            let mut n = n as isize; // possibly reduce 64bit math

            // decode 2 more chars, if > 2 chars
            if n >= 100 {
                let d1 = (n % 100) << 1;
                n /= 100;
                buf_ptr = buf_ptr.offset(-2);
                ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr, 2);
            }

            // decode last 1 or 2 chars
            if n < 10 {
                buf_ptr = buf_ptr.offset(-1);
                *buf_ptr = (n as u8) + b'0';
            } else {
                let d1 = n << 1;
                buf_ptr = buf_ptr.offset(-2);
                ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr, 2);
            }

            if is_negative {
                buf_ptr = buf_ptr.offset(-1);
                *buf_ptr = b'-';
            }

            let buf_slice =
                slice::from_raw_parts(buf_ptr, buf_ptr_start as usize - buf_ptr as usize);

            writer.write_all(buf_slice).unwrap();
        }
    }

    pub trait Writable {
        fn display<W: Write>(&self, writer: &mut W);
    }

    impl Writable for str {
        #[inline]
        fn display<W: Write>(&self, writer: &mut W) {
            writer.write_all(self.as_bytes()).unwrap()
        }
    }

    impl<'a> Writable for &'a str {
        #[inline]
        fn display<W: Write>(&self, writer: &mut W) {
            writer.write_all(self.as_bytes()).unwrap()
        }
    }

    impl Writable for String {
        #[inline]
        fn display<W: Write>(&self, writer: &mut W) {
            writer.write_all(self.as_bytes()).unwrap()
        }
    }

    impl Writable for bool {
        #[inline]
        fn display<W: Write>(&self, writer: &mut W) {
            let s = if *self { "Yes" } else { "No" };
            writer.write_all(s.as_bytes()).unwrap();
        }
    }

    macro_rules! impl_writable_int {
        ($($int:ty)*) => {
            $(
                impl Writable for $int {
                    #[allow(unused_comparisons)]
                    fn display<W: Write>(&self, writer: &mut W) {
                        let is_negative = !(*self >= 0);
                        let abs = if is_negative {
                            (!*self as u64).wrapping_add(1)
                        } else {
                            *self as u64
                        };
                        write_int(writer, abs, is_negative);
                    }
                }
            )*
        };
    }

    macro_rules! impl_writable_float {
        ($($float:ty)*) => {
            $(
                impl Writable for $float {
                    #[inline]
                    fn display<W: Write>(&self, writer: &mut W) {
                        write!(writer, "{}", *self).unwrap();
                    }
                }
            )*
        }
    }

    impl_writable_int!(u8 u16 u32 u64 usize i8 i16 i32 i64 isize);
    impl_writable_float!(f32 f64);

    pub static mut SCANNER: *mut StdinScanner = 0 as *mut StdinScanner;
    pub static mut WRITER: *mut StdoutWriter = 0 as *mut StdoutWriter;

    #[inline]
    pub fn atcoder_initialize() {
        unsafe {
            SCANNER = mem::transmute(Box::new(StdinScanner::new()));
            WRITER = mem::transmute(Box::new(StdoutWriter::new()));
        }
    }

    #[inline]
    pub fn atcoder_finish() {
        unsafe {
            (*WRITER).flush().unwrap();
        }
    }
}

macro_rules! input {
    () => {};
    (@scanner $scanner:ident, @pred [ $($pred:tt)* ], ($var1:tt, $var2:tt) : [($t1:tt, $t2:tt) ; $len:expr]) => {
        let mut $var1 = Vec::with_capacity($len as usize);
        let mut $var2 = Vec::with_capacity($len as usize);

        for _ in 0..$len {
            $var1.push(scan!($scanner, $t1));
            $var2.push(scan!($scanner, $t2));
        }
    };
    (@scanner $scanner:ident, @pred [ $($pred:tt)* ], $var:tt : $t:tt) => {
        let $($pred)* $var = scan!($scanner, $t);
    };
    (@scanner $scanner:ident,) => {};
    (@scanner $scanner:ident, $var:tt : $t:tt) => {
        input!(@scanner $scanner, @pred [], $var : $t);
    };
    (@scanner $scanner:ident, mut $var:tt : $t:tt) => {
        input!(@scanner $scanner, @pred [mut], $var : $t);
    };
    (@scanner $scanner:ident, $var:tt : $t:tt, $($r:tt)*) => {
        input!(@scanner $scanner, $var : $t);
        input!(@scanner $scanner, $($r)*);
    };
    (@scanner $scanner:ident, mut $var:tt : $t:tt, $($r:tt)*) => {
        input!(@scanner $scanner, mut $var : $t);
        input!(@scanner $scanner, $($r)*);
    };
    ($($r:tt)*) => {
        let scanner_ref = unsafe { &mut *$crate::utils::SCANNER };
        input!(@scanner scanner_ref, $($r)*);
    }
}

macro_rules! scan {
    ($scanner:ident, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| scan!($scanner, $t)).collect::<Vec<_>>()
    };
    ($scanner:ident, usize1) => {
        scan!($scanner, usize) - 1
    };
    ($scanner:ident, line) => {
        $scanner.readl().to_string()
    };
    ($scanner:ident, $t:ty) => {
        $scanner.read::<$t>()
    };
}

macro_rules! pprint {
    ($value:expr) => {
        unsafe {
            (*$crate::utils::WRITER).write($value);
        }
    };
    ($value:expr, $($r:tt)*) => {
        let writer = unsafe { &mut *$crate::utils::WRITER };
        writer.write($value);
        writer.write(" ");
        pprint!($($r)*);
    };
}

macro_rules! pprintln {
    ($value:expr) => {
        unsafe {
            (*$crate::utils::WRITER).writeln($value);
        }
    };
    ($value:expr, $($r:tt)*) => {
        let writer = unsafe { &mut *$crate::utils::WRITER };
        writer.write($value);
        writer.write(" ");
        pprintln!($($r)*);
    };
}

macro_rules! atcoder_main {
    ($func:ident) => {
        fn main() {
            $crate::utils::atcoder_initialize();
            $func();
            $crate::utils::atcoder_finish();
        }
    };
}

macro_rules! debug {
    ($e:expr) => {
        #[cfg(debug_assertions)]
        dbg!($e)
    }
}

use std::collections::BinaryHeap;

#[derive(PartialEq, Eq, Clone, Copy)]
struct Reverse<T>(pub T);

impl<T: PartialOrd> PartialOrd for Reverse<T> {
    fn partial_cmp(&self, rhs: &Reverse<T>) -> Option<std::cmp::Ordering> {
        self.0.partial_cmp(&rhs.0).map(|v| v.reverse())
    }
}

impl<T: Ord> Ord for Reverse<T> {
    fn cmp(&self, rhs: &Reverse<T>) -> std::cmp::Ordering {
        self.0.cmp(&rhs.0).reverse()
    }
}

fn solve(graph: &Vec<Vec<(usize, u64)>>, l: u64, s: usize, t: usize) -> i64 {
    let mut queue = BinaryHeap::with_capacity(graph.len() / 2);
    let mut optimal = vec![(0, std::i64::MAX); graph.len()];

    queue.push((Reverse(0), l, s));
    optimal[s] = (l, 0);

    while !queue.is_empty() {
        let (cnt, remain, pos) = queue.pop().unwrap();
        for &(next, dis) in graph[pos].iter() {
            let (remain, cnt) = if remain < dis {
                (l - dis, Reverse(cnt.0 + 1))
            } else {
                (remain - dis, cnt)
            };

            if cnt.0 < optimal[next].1 || (cnt.0 == optimal[next].1 && remain > optimal[next].0) {
                optimal[next] = (remain, cnt.0);

                if next != t {
                    queue.push((cnt, remain, next));
                }
            }
        }
    };

    if optimal[t].1 == std::i64::MAX {
        -1
    } else {
        optimal[t].1
    }
}

fn run() {
    input! {
        n: usize,
        m: usize,
        l: u64,
    }

    let mut graph = vec![Vec::<(usize, u64)>::new(); n];

    for _ in 0..m {
        input! {
            a: usize1,
            b: usize1,
            c: u64,
        }

        if c <= l {
            graph[a].push((b, c));
            graph[b].push((a, c));
        }
    }

    input! {
        q: usize,
    }

    for _ in 0..q {
        input! {
            s: usize1,
            t: usize1,
        }

        let ans = solve(&graph, l, s, t);
        pprintln!(ans);
    }
}

atcoder_main!(run);