привет , помоги с решением задачи на алгоритм динамическое программирование по профилю на с++

Задача D. Прочные замощения
Имя входного файла: Имя выходного файла: Ограничение по времени: Ограничение по памяти:
j3.in j3.out
1 секунда
256 мегабайт
Замощение прямоугольника n х m доминошками 2 х 1 будем называть прочным, если не существует прямой, пересекающей внутренность прямоугольника m × n и не пересекающей внутренность ни одной доминошки. Например, приведенные на иллюстрации замощения (а) и (b) замощения (с) и (d) нет.
А сколько существует прочных замощений прямоугольника m х n?
Формат входного файла
В первой строке два натуральных числа т и п (1 ≤ m ≤ 8,1 ≤ n ≤ 16)
доски.
Формат выходного файла
Выведите одно число количество прочных замощений данного прямоугольника.
ширина и высота
вот пример входных данных
ввод 2 2 ответ 0
ввод 5 6 ответ 6
чтобы понять лучше условие задачи, подумай над примером входных данных

вот такой код я написал, но он уже на первом тесте не проходит изза превышения по памяти, наверное не стоит использовать мапу и собственную структуру, а просто вести dp и придумать переход между масками предыдущего и нынешнего столбца 
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);

    int m, n;
    cin >> n >> m;

    int V = m-1;
    int H = n-1;
    int total_lines = V + H;

    unsigned int full_coverage = (V ==0? 0 : (1U << V)-1) | (H ==0? 0 : ((1U << H)-1) << V);

    unordered_map<uint, ll> current;
    current[0] =1;

    for(int row=0; row <n; row++){
        unordered_map<uint, ll> next;

        for(auto &[key, cnt] : current){
            uint mask = key >> total_lines;
            uint coverage = key & ((1U << total_lines)-1);
            struct State {
                int pos;
                uint current_mask;
                uint new_mask;
                uint current_coverage;
            };

            vector<State> stack;
            stack.push_back({0, mask, 0, coverage});

            while(!stack.empty()){
                State s = stack.back();
                stack.pop_back();
                if(s.pos >=m){
                    uint new_key = (s.new_mask << total_lines) | s.current_coverage;
                    next[new_key] += cnt;
                    continue;
                }
                if(s.current_mask & (1U << s.pos)){
                    stack.push_back({s.pos +1, s.current_mask, s.new_mask, s.current_coverage});
                }
                else{
                    if(s.pos < m-1 && !(s.current_mask & (1U << (s.pos +1)))){
                        uint new_cov = s.current_coverage | (1U << s.pos);
                        uint updated_new_mask = s.new_mask;
                        stack.push_back({s.pos +2, s.current_mask, updated_new_mask, new_cov});
                    }
                    if(row < n-1){
                        uint new_cov = s.current_coverage | (1U << (V + row));
                        uint updated_new_mask = s.new_mask | (1U << s.pos);
                        stack.push_back({s.pos +1, s.current_mask, updated_new_mask, new_cov});
                    }
                }
            }
        }
        current = move(next);
    }

    ll total =0;
    for(auto &[key, cnt] : current){
        uint coverage = key & ((1U << total_lines)-1);
        if(coverage == full_coverage){
            total += cnt;
        }
    }

    cout << total;

    return 0;
}