# luoguP5074 Eat the Trees

https://www.luogu.org/problemnew/show/P5074

$left$ 表示左插头的状态，$up$ 表示右插头的状态

#include <bits/stdc++.h>
#define Fast_cin ios::sync_with_stdio(false), cin.tie();
#define For(i, a, b) for(register int i = a; i <= b; i++)
#define Forr(i, a, b) for(register int i = a; i >= b; i--)
#define DEBUG(x) cerr << "DEBUG" << x << " >>> " << endl;
using namespace std;

typedef unsigned long long ull;
typedef long long ll;

template <typename _T>
f = 0; _T fu = 1; char c = getchar();
while(c < '0' || c > '9') { if(c == '-') fu = -1; c = getchar(); }
while(c >= '0' && c <= '9') { f = (f << 3) + (f << 1) + (c & 15); c = getchar(); }
f *= fu;
}

template <typename T>
void print(T x) {
if(x < 0) putchar('-'), x = -x;
if(x < 10) putchar(x + 48);
else print(x / 10), putchar(x % 10 + 48);
}

template <typename T>
void print(T x, char t) {
print(x); putchar(t);
}

const int mod = 5801, N = mod + 100;

ll f[2][N], ans;
int a[15][15], tot[2], v[2][N], nxt[N], head[N], bin[15];
int T, n, m, now, end1, end2;

void ins(int zt, ll val) {
int u = zt % mod;
for(register int i = head[u]; i; i = nxt[i])
if(v[now][i] == zt) {
f[now][i] += val;
return;
}
f[now][tot[now]] = val; v[now][tot[now]] = zt;
}

void sol() {
tot[now] = 1; f[now][1] = 1; v[now][1] = 0;
for(register int i = 1; i <= n; i++) {
for(register int j = 1; j <= tot[now]; j++) v[now][j] <<= 2;
for(register int j = 1; j <= m; j++) {
for(register int k = 1; k <= tot[now ^ 1]; k++) {
int zt = v[now ^ 1][k]; ll val = f[now ^ 1][k];
int t1 = (zt >> ((j << 1) - 2)) & 3, t2 = (zt >> (j << 1)) & 3;
if(a[i][j] == 0) {
if(t1 == 0 && t2 == 0) ins(zt, val);
} else if(t1 == 0 && t2 == 0) {
if(a[i][j + 1] && a[i + 1][j]) ins(zt ^ bin[j - 1] ^ (bin[j] << 1), val);
} else if(t1 == 0 && t2 != 0) {
if(a[i][j + 1]) ins(zt, val);
if(a[i + 1][j]) ins(zt ^ (bin[j] * t2) ^ (bin[j - 1] * t2), val);
} else if(t1 != 0 && t2 == 0) {
if(a[i + 1][j]) ins(zt, val);
if(a[i][j + 1]) ins(zt ^ (bin[j] * t1) ^ (bin[j - 1] * t1), val);
} else if(t1 == 1 && t2 == 1) {
int nowv = 1;
for(register int t = j + 1; t < m; t++) {
int t3 = (zt >> (t << 1)) & 3;
if(t3 == 1) nowv++;
if(t3 == 2) nowv--;
if(!nowv) { ins(zt ^ bin[j - 1] ^ bin[j] ^ (bin[t] * 3), val); break; }
}
} else if(t1 == 2 && t2 == 2) {
int nowv = 1;
for(register int t = j - 2; t > 0; t--) {
int t3 = (zt >> (t << 1)) & 3;
if(t3 == 1) nowv--;
if(t3 == 2) nowv++;
if(!nowv) { ins(zt ^ (bin[j - 1] << 1) ^ (bin[j] << 1) ^ (bin[t] * 3), val); break; }
}
} else if(t1 == 2 && t2 == 1) {
ins(zt ^ (bin[j - 1] << 1) ^ bin[j], val);
} else if(i == end1 && j == end2) {
ans += val;
} else ins(zt ^ bin[j - 1] ^ (bin[j] << 1), val);
}
}
}
}

int main() {
for(register int i = 1; i <= 11; i++) bin[i] = bin[i - 1] << 2;
for(register int Case = 1; Case <= T; Case++) {
memset(a, 0, sizeof(a));
}