Problem:
Score : 700 points

Problem Statement

Haiku is a short form of Japanese poetry. A Haiku consists of three phrases with 5, 7 and 5 syllables, in this order.

Iroha is looking for X,Y,Z-Haiku (defined below) in integer sequences.

Consider all integer sequences of length N whose elements are between 1 and 10, inclusive. Out of those 10^N sequences, how many contain an X,Y,Z-Haiku?

Here, an integer sequence a_0, a_1, ..., a_{N-1} is said to contain an X,Y,Z-Haiku if and only if there exist four indices x, y, z, w (0 ≦ x < y < z < w ≦ N) such that all of the following are satisfied:

a_x + a_{x+1} + ... + a_{y-1} = X

a_y + a_{y+1} + ... + a_{z-1} = Y

a_z + a_{z+1} + ... + a_{w-1} = Z

Since the answer can be extremely large, print the number modulo 10^9+7.

Constraints

3 ≦ N ≦ 40

1 ≦ X ≦ 5

1 ≦ Y ≦ 7

1 ≦ Z ≦ 5

Input

The input is given from Standard Input in the following format:

N X Y Z

Output

Print the number of the sequences that contain an X,Y,Z-Haiku, modulo 10^9+7.

Sample Input 1

3 5 7 5

Sample Output 1

1

Here, the only sequence that contains a 5,7,5-Haiku is [5, 7, 5].

Sample Input 2

4 5 7 5

Sample Output 2

34

Sample Input 3

37 4 2 3

Sample Output 3

863912418

Sample Input 4

40 5 7 5

Sample Output 4

562805100

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

const F: usize = 10;

struct Node {
    fail: usize,
    next: [usize; F],
}

impl Node {
    fn new() -> Self {
        Node {
            fail: 0,
            next: [0; F],
        }
    }
}

struct AhoCorasick {
    node: Vec<Node>,
}

impl AhoCorasick {
    fn new() -> Self {
        let root = Node::new();
        AhoCorasick {
            node: vec![root],
        }
    }
    fn insert(&mut self, s: &[usize]) -> usize {
        let mut pos = 0;
        let node = &mut self.node;
        for &c in s.iter() {
            if node[pos].next[c] == 0 {
                node[pos].next[c] = node.len();
                node.push(Node::new());
            }
            pos = node[pos].next[c];
        }
        pos
    }
    fn build(&mut self) {
        let mut q = std::collections::VecDeque::new();
        let node = &mut self.node;
        for &v in node[0].next.iter() {
            if v != 0 {
                q.push_back(v);
            }
        }
        while let Some(v) = q.pop_front() {
            for c in 0..F {
                let u = node[v].next[c];
                if u == 0 {
                    continue;
                }
                let mut fail = node[v].fail;
                while fail > 0 && node[fail].next[c] == 0 {
                    fail = node[fail].fail;
                }
                node[u].fail = node[fail].next[c];
                q.push_back(u);
            }
        }
    }
    fn next(&self, mut state: usize, ch: usize) -> usize {
        let node = &self.node;
        while state > 0 && node[state].next[ch] == 0 {
            state = node[state].fail;
        }
        node[state].next[ch]
    }
    fn len(&self) -> usize {
        self.node.len()
    }
}

fn enumerate(n: usize) -> Vec<Vec<usize>> {
    if n == 0 {
        return vec![vec![]];
    }
    let mut ans = vec![];
    for i in 1..=std::cmp::min(F, n) {
        let mut a = enumerate(n - i);
        a.iter_mut().for_each(|a| a.push(i - 1));
        ans.append(&mut a);
    }
    ans
}

fn run() {
    proconio::input! {
        n: usize,
        x: [usize; 3],
    }
    let mut a = vec![];
    for x in x {
        let b = enumerate(x);
        a.push(b);
    }
    let mut aho = AhoCorasick::new();
    let mut accept = vec![];
    for x in a[0].iter() {
        for y in a[1].iter() {
            for z in a[2].iter() {
                let mut p = vec![];
                p.extend_from_slice(x);
                p.extend_from_slice(y);
                p.extend_from_slice(z);
                accept.push(aho.insert(&p));
            }
        }
    }
    aho.build();
    accept.sort();
    accept.dedup();
    let mut dp = vec![0u64; aho.len()];
    dp[0] = 1;
    const MOD: u64 = 1_000_000_007;
    let mut ans = 0;
    for _ in 0..n {
        let mut next = vec![0; aho.len()];
        for (i, &v) in dp.iter().enumerate().filter(|p| *p.1 != 0) {
            for j in 0..F {
                let u = aho.next(i, j);
                next[u] += v;
            }
        }
        for (dp, next) in dp.iter_mut().zip(next.iter()) {
            *dp = *next % MOD;
        }
        ans *= 10;
        for a in accept.iter() {
            ans += dp[*a];
            dp[*a] = 0;
        }
        ans %= MOD;
    }
    println!("{}", ans);
}

fn main() {
    run();
}