Problem:
Score : 100 points

Problem Statement

You are given three strings A, B and C. Check whether they form a word chain.

More formally, determine whether both of the following are true:

The last character in A and the initial character in B are the same.

The last character in B and the initial character in C are the same.

If both are true, print YES. Otherwise, print NO.

Constraints

A, B and C are all composed of lowercase English letters (a - z).

1 ≤ |A|, |B|, |C| ≤ 10, where |A|, |B| and |C| are the lengths of A, B and C, respectively.

Input

Input is given from Standard Input in the following format:

A B C

Output

Print YES or NO.

Sample Input 1

rng gorilla apple

Sample Output 1

YES

They form a word chain.

Sample Input 2

yakiniku unagi sushi

Sample Output 2

NO

A and B form a word chain, but B and C do not.

Sample Input 3

a a a

Sample Output 3

YES

Sample Input 4

aaaaaaaaab aaaaaaaaaa aaaaaaaaab

Sample Output 4

NO

Solution in Rust (1.15.1) (judge verdict: Runtime Error)

use std::io::prelude::*;
use std::{io};
use std::collections::{HashMap, HashSet, VecDeque};
use std::cmp::Ordering;

fn string_to_nums(s: String) -> Vec<isize> {
    let mut v = Vec::new();
    for part in s.split_whitespace() {
        v.push(part.parse::<isize>().unwrap())
    }
    v
}

fn read_a_line() -> String {
    let mut s = String::new();
    assert!(io::stdin().read_line(&mut s).is_ok());
    s.trim().to_string()
}

fn read_nums() -> Vec<isize> {
    string_to_nums(read_a_line())
}

fn main() {
    let w_tot = read_nums();
    let n = w_tot[0] as i64;
    let w_tot = w_tot[1] as i64;

    let mut v: Vec<(i64, i64)> = vec![];
    for _ in 0..n {
        let t = read_nums();
        v.push((t[0] as i64, t[1] as i64));
    }
    v.sort_by(|&(w1, v1), &(w2, v2)| match w1.cmp(&w2) {
        Ordering::Less => Ordering::Greater,
        Ordering::Greater => Ordering::Less,
        Ordering::Equal =>  v2.cmp(&v1)
    });
    let mut m: HashMap<i64, i64> = HashMap::new();
    m.insert(0, 0);
    let mut w_cache: i64 = -1;
    let w0_tri = v[0].0 * 4;
    for &(w, v) in v.iter() {
        let mut keys: Vec<i64> = Vec::with_capacity(m.len());
        {
            for k in m.keys() { keys.push(*k); }
        }
        for k in keys {
            let v_now;
            {
                v_now = *m.get(&k).unwrap();
            }
            if k + w <= w_tot {
                let v_this;
                {
                    v_this = *m.get(&(k + w)).unwrap_or(&-1);
                }
                if v_now + v > v_this {
                    m.insert(k + w, v_now + v);
                    w_cache = w_tot;
                }
            }
            if k < w_cache - w0_tri {
                m.remove(&k);
            }
        }
    }
    println!("{}", m.values().max().unwrap_or(&0));
}