Problem:
Score : 500 points

Problem Statement

A robot is put at the origin in a two-dimensional plane.
Initially, the robot is facing in the positive x-axis direction.

This robot will be given an instruction sequence s.
s consists of the following two kinds of letters, and will be executed in order from front to back.

F : Move in the current direction by distance 1.

T : Turn 90 degrees, either clockwise or counterclockwise.

The objective of the robot is to be at coordinates (x, y) after all the instructions are executed.
Determine whether this objective is achievable.

Constraints

s consists of F and T.

1 \leq |s| \leq 8 000

x and y are integers.

|x|, |y| \leq |s|

Input

Input is given from Standard Input in the following format:

s
x y

Output

If the objective is achievable, print Yes; if it is not, print No.

Sample Input 1

FTFFTFFF
4 2

Sample Output 1

Yes

The objective can be achieved by, for example, turning counterclockwise in the first T and turning clockwise in the second T.

Sample Input 2

FTFFTFFF
-2 -2

Sample Output 2

Yes

The objective can be achieved by, for example, turning clockwise in the first T and turning clockwise in the second T.

Sample Input 3

FF
1 0

Sample Output 3

No

Sample Input 4

TF
1 0

Sample Output 4

No

Sample Input 5

FFTTFF
0 0

Sample Output 5

Yes

The objective can be achieved by, for example, turning counterclockwise in the first T and turning counterclockwise in the second T.

Sample Input 6

TTTT
1 0

Sample Output 6

No

Solution in Rust (1.15.1) (judge verdict: Accepted)

use std::io;
use std::cmp;
use std::collections::HashMap;

// read a line(without line feed)
fn read_line() -> String {
    let mut in_str = String::new();
    io::stdin().read_line(&mut in_str).unwrap();
    return in_str.trim().to_string();
}

// read wods on a line
pub fn read_words_in_line() -> Vec<String> {
    let s = read_line();
    return s.split_whitespace().map(|x| x.to_string()).collect::<Vec<String>>()
}

// read type t on a line
pub fn read_t_in_line<T : std::str::FromStr>() -> Vec<T> {
    let mut v : Vec<T> = Vec::new();
    for e in read_words_in_line().iter().map(|x| x.parse::<T>()) {
        if let Ok(r) = e {
            v.push(r);
        }
        else{
            return Vec::new();
        }
    }
    return v;
}

// sort slice
pub fn sort<T : std::cmp::Ord>(slice : &mut [T]) {
    slice.sort();
}
// sort slice by reverse order
pub fn sort_rev<T : std::cmp::Ord>(slice : &mut [T]) {
    slice.sort_by(|x, y| y.cmp(x));
}

pub fn min<T : std::cmp::Ord>(a : T, b : T) -> T{
    return cmp::min(a, b);
}

pub fn max<T : std::cmp::Ord>(a : T, b : T) -> T{
    return cmp::max(a, b);
}



// 原点0からgoalまでたどり着けるか調べる
fn check(seq : Vec<i32>, goal : i32) -> bool{
    const BASE : usize = 16000;
    let mut used =  [[false ; BASE * 2] ; 2];
    let mut c_idx = 0;
    let mut n_idx = 1;

    used[c_idx][BASE] = true;

    for s in seq {
        for i in 0..used[c_idx].len() {
            used[n_idx][i] = false;
        }
        for i in 0..used[c_idx].len(){
            if used[c_idx][i] {
                used[n_idx][((i as i32) + s) as usize] = true;
                used[n_idx][((i as i32) - s) as usize] = true;
            }
        }
        std::mem::swap(& mut c_idx, & mut n_idx);
    }

    // goal + 8000にいるか調べる
    return used[c_idx][(goal + BASE as i32) as usize];
}
    

fn main() {

    let s = read_line();
    let v = read_t_in_line::<i32>();
    let (x, y) = (v[0], v[1]);

    let mut cnt = 0;
    let mut prv = s.as_bytes()[0];

    let mut seq : Vec<(u8, i32)> = Vec::new();

    for c in s.chars() {
        // 前と同じ場合
        if prv == c as u8 {
            cnt += 1;
        }
        // 変化した場合、cnt分から次の方向を決める
        else{
            seq.push((prv, cnt));
            cnt = 1;
        }
        prv = c as u8;
    }

    if cnt != 0 {
        seq.push((prv, cnt));
    }

    // (F)TFTFTFT ...
    // というsequenceができたので、さらに偶数回のT、奇数回のTが出る場所で場合分けする

    let mut slice : &[(u8, i32)] = &seq[..];
    let mut init_x = 0;

    // 最初は必ずXの正の方向なので除外する
    if seq[0].0 == 'F' as u8 {
        slice = &seq[1..];
        init_x = seq[0].1;
    }

    let mut xseq : Vec<i32> = Vec::new();
    let mut yseq : Vec<i32> = Vec::new();
    
    let mut ang = 0; // 0:x, 1:y
    // 残ったsliceを順番に調べる
    for i in 0..slice.len() {
        if i * 2 + 1 >= slice.len() {
            break;
        }
        // T, Fの順番になっているはず
        if slice[i * 2 + 0].1 % 2 == 1 {
            ang ^= 1;
        }
        
        if ang == 0 {
            xseq.push(slice[i * 2 + 1].1);
        }
        else {
            yseq.push(slice[i * 2 + 1].1);
        }
    }
    
    // xseqとyseqから、それぞれゴールまでたどり着けるかどうか調べる
    // DP or BFS
    // BFSのほうがわかりやすいし実装も楽かな?
    if check(xseq, x - init_x) && check(yseq, y) {
        println!("Yes");
    }
    else{
        println!("No");
    }
    
}