Problem:
Problem Statement
JAG land is a country, which is represented as an $M \times M$ grid. Its top-left cell is $(1, 1)$ and its bottom-right cell is $(M, M)$.
Suddenly, a bomber invaded JAG land and dropped bombs to the country. Its bombing pattern is always fixed and represented by an $N \times N$ grid. Each symbol in the bombing pattern is either
X
or
.
. The meaning of each symbol is as follows.
X
: Bomb
.
: Empty
Here, suppose that a bomber is in $(br, bc)$ in the land and drops a bomb. The cell $(br + i - 1, bc + j - 1)$ will be damaged if the symbol in the $i$-th row and the $j$-th column of the bombing pattern is
X
($1 \le i, j \le N$).
Initially, the bomber reached $(1, 1)$ in JAG land. The bomber repeated to move to either of $4$-directions and then dropped a bomb just $L$ times. During this attack, the values of the coordinates of the bomber were between $1$ and $M - N + 1$, inclusive, while it dropped bombs. Finally, the bomber left the country.
The moving pattern of the bomber is described as $L$ characters. The $i$-th character corresponds to the $i$-th move and the meaning of each character is as follows.
U
: Up
D
: Down
L
: Left
R
: Right
Your task is to write a program to analyze the damage situation in JAG land. To investigate damage overview in the land, calculate the number of cells which were damaged by the bomber at least $K$ times.
Input
The input consists of a single test case in the format below.
$N$ $M$ $K$ $L$
$B_{1}$
$\vdots$
$B_{N}$
$S$
The first line contains four integers $N$, $M$, $K$ and $L$($1 \le N < M \le 500$, $1 \le K \le L \le 2 \times 10^{5}$).
The following $N$ lines represent the bombing pattern.
$B_i$ is a string of length $N$. Each character of $B_i$ is either
X
or
.
. The last line denotes the moving pattern. 
$S$ is a string of length $L$, which consists of either
U
,
D
,
L
or
R
. 
It's guaranteed that the values of the coordinates of the bomber are between $1$ and $M - N + 1$, inclusive, while it drops bombs in the country.
Output
Print the number of cells which were damaged by the bomber at least $K$ times.
Examples
Input
Output
2 3 2 4
XX
X.
RDLU
3
7 8 3 5
.XXX.X.
X..X.X.
...XX.X
XX.XXXX
..XXXX.
X.X....
..XXXXX
DRULD
26

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1ll << 60;
#define REP(i, n) for (ll i=0; i<ll(n); i++)
template <class T> using V = vector<T>;
template<class A, class B>
bool chmax(A &a, B b) { return a < b && (a = b, true); }
template<class A, class B>
bool chmin(A &a, B b) { return b < a && (a = b, true); }

template <int MD, int g = 3>
struct ModInt {
  using M = ModInt;
  const static inline M G = g;
  unsigned int v;
  ModInt() : v(0) {}
  ModInt(ll w) : v(w % MD + MD) {
    if(v >= MD) v -= MD;
  }
  static M raw(unsigned int v) {
    M res;
    res.v = (v < MD) ? v : v - MD;
    return res;
  }
  explicit operator bool() const {
    return v != 0;
  }
  M operator-() const {
    return M() - *this;
  }
  M operator+(M r) const {
    return raw(v + r.v);
  }
  M operator-(M r) const {
    return raw(v + MD - r.v);
  }
  M operator*(M r) const {
    return raw(ll(v) * r.v % MD);
  }
  M operator/(M r) const {
    return *this * r.inv();
  }
  M& operator+=(M r) {
    return *this = *this + r;
  }
  M& operator-=(M r) {
    return *this = *this - r;
  }
  M& operator*=(M r) {
    return *this = *this * r;
  }
  M& operator/=(M r) {
    return *this = *this / r;
  }
  bool operator==(M r) const {
    return v == r.v;
  }
  M pow(ll n) const {
    M x = *this, r = 1;
    while (n) {
      if (n & 1) r *= x;
      x *= x;
      n >>= 1;
    }
    return r;
  }
  M inv() const {
    return pow(MD - 2);
  }
  friend ostream& operator<<(ostream& os, M r) {
    return os << r.v;
  }
};
// using Mint = ModInt<998244353, 3>;

template <class Mint>
void nft(bool type, V<Mint>& a) {
  int n = int(a.size()), s = 0;
  while ((1 << s) < n) s++;
  assert(1 << s == n);
  static V<Mint> ep;
  while (int(ep.size()) <= s) {
    ep.push_back(Mint::G.pow(Mint(-1).v >> ep.size()));
  }
  V<Mint> b(n);
  REP(i, s) {
    int w = 1 << (s - i - 1);
    Mint now = 1;
    for (int y = 0; y < n / 2; y += w) {
      REP(x, w) {
        auto l = a[y << 1 | x];
        auto r = now * a[y << 1 | x | w];
        b[y | x] = l + r;
        b[y | x | n >> 1] = l - r;
      }
      now *= ep[i + 1];
    }
    swap(a, b);
  }
  if(type) reverse(a.begin() + 1, a.end());
}

using MI = ModInt<998244353, 3>;

int main() {
    cin.tie(0)->sync_with_stdio(0);
    int n, m, k, l; cin >> n >> m >> k >> l;
    m = bit_ceil((unsigned)m);
    V<V<MI>> a(m, V<MI>(m));
    REP(i, n) {
        string line; cin >> line;
        REP(j, n) {
            a[i][j] = line[j] == 'X';
        }
    }
    string s; cin >> s;
    V<V<MI>> b(m, V<MI>(m));
    int x = 0, y = 0;
    for(char c : s) {
        if(c == 'U') x--;
        if(c == 'D') x++;
        if(c == 'L') y--;
        if(c == 'R') y++;
        b[x][y] += 1;
    }
    auto nft2d = [&](bool b, V<V<MI>>& a) {
        REP(i, m) nft(b, a[i]);
        REP(j, m) {
            V<MI> col(m);
            REP(i, m) col[i] = a[i][j];
            nft(b, col);
            REP(i, m) a[i][j] = col[i];
        }
    };
    auto dbg = [&](const V<V<MI>>& a) {
        cerr << "=======" << endl;
        for(auto&& v : a) {
            for(auto&& c : v) cerr << ' ' << c.v;
            cerr << endl;
        }
    };
    nft2d(0, a);
    nft2d(0, b);
    MI minv = MI(m).inv();
    minv *= minv;
    REP(i, m) REP(j, m) {
        a[i][j] *= b[i][j] * minv;
    }
    nft2d(1, a);
    int ans = 0;
    REP(i, m) REP(j, m) ans += a[i][j].v >= k;
    cout << ans << '\n';
}
accuracy: 1
time_ms: 10
memory_kb: 5632
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;

const double pi = acos(-1.0);

using data_type = complex<double>;
using matrix = vector<vector<data_type>>;

vector<data_type> fft(vector<data_type> v, bool inv = false) {
    const int n = v.size();
    double theta = 2 * pi / n * (inv ? -1 : 1);
    for(int m = n; m >= 2; m >>= 1) {
        int mh = m >> 1;
        data_type theta_i(0, theta);
        for(int i = 0; i < mh; ++i) {
            auto w = exp((data_type)i * theta_i);
            for(int j = i; j < n; j += m) {
                auto x = v[j] - v[j + mh];
                v[j] = v[j] + v[j + mh];
                v[j + mh] = w * x;
            }
        }
        theta *= 2;
    }
    for(int i = 0, j = 1; j < n - 1; ++j) {
        for(int k = n >> 1; k > (i ^= k); k >>= 1);
        if(j < i) {
            swap(v[i], v[j]);
        }
    }
    if(inv) {
        for(auto& x : v) x /= n;
    }
    return v;
}

matrix transpose(matrix a) {
    const int n = a.size(), m = a[0].size();
    matrix res(m, vector<data_type>(n));
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < m; ++j) {
            res[i][j] = a[j][i];
        }
    }
    return res;
}

matrix fft2d(matrix a, bool inv = false) {
    for(int t = 0; t < 2; ++t) {
        for(auto& v : a) {
            v = fft(move(v), inv);
        }
        a = transpose(move(a));
    }
    return a;
}

matrix conv2d(matrix a, matrix b) {
    const int nt = a.size() + b.size() - 1;
    const int mt = a[0].size() + b[0].size() - 1;
    int n = 1, m = 1;
    while(n < nt) n <<= 1;
    while(m < mt) m <<= 1;
    a.resize(n), b.resize(n);
    for(int i = 0; i < n; ++i) {
        a[i].resize(m);
        b[i].resize(m);
    }
    a = fft2d(move(a)), b = fft2d(move(b));
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < m; ++j) {
            a[i][j] *= b[i][j];
        }
    }
    return fft2d(move(a), true);
}

int main() {
    int n, m, K, l; cin >> n >> m >> K >> l;
    matrix dat(n, vector<data_type>(n));
    for(int i = 0; i < n; ++i) {
        string s; cin >> s;
        for(int j = 0; j < n; ++j) {
            if(s[j] == 'X') {
                dat[i][j] = data_type{1, 0};
            }
        }
    }
    string s; cin >> s;
    vector<vector<int>> tcnt(m, vector<int>(m));
    for(int y = 0, x = 0, i = 0; i < (int)s.size(); ++i) {
        if(s[i] == 'U') --y;
        if(s[i] == 'D') ++y;
        if(s[i] == 'R') ++x;
        if(s[i] == 'L') --x;
        tcnt[y][x]++;
    }
    matrix cnt(m, vector<data_type>(m));
    for(int i = 0; i < m; ++i) {
        for(int j = 0; j < m; ++j) {
            cnt[i][j] = data_type{(double)tcnt[i][j], 0};
        }
    }

    auto res = conv2d(cnt, dat);
    int ans = 0;
    for(int i = 0; i < m; ++i) {
        for(int j = 0; j < m; ++j) {
            const int val = (int)(real(res[i][j]) + 0.5);
            ans += val >= K;
        }
    }

    cout << ans << endl;
}
accuracy: 1
time_ms: 290
memory_kb: 61936
final_rank: 13

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;
 
 
#define MAX 25
typedef complex<double> COMPLEX;
typedef vector<COMPLEX> V;
typedef vector<V> MATRIX;
 
 
ll size_A,size_B,K,L;
char map_A[505][505],map_B[505][505];
char buf[200005];
 
 
struct Info{
    Info(int arg_left,int arg_right){
        left = arg_left;
        right = arg_right;
    }
    int left,right;
};
 
int POW[MAX];
int LR_rev[1000005];
vector<Info> info;
vector<COMPLEX> MULT[MAX];
 
 
void calc_swap_pair(int N,int num_pow){
 
    LR_rev[0] = 0;
 
    for(int i = 1; i < N; i++){
 
        if(i%2 == 1){
 
            LR_rev[i] = LR_rev[i-1]+POW[num_pow-1]; //1を足す代わりにPOW[num_pow-1]を足す
 
        }else{
 
            LR_rev[i] = LR_rev[i/2]/2; //半分のインデックスの値に、2を掛ける代わりに2で割る
        }
 
        if(i < LR_rev[i]){
            info.push_back(Info(i,LR_rev[i]));
        }
    }
}
 
void calc_COMPLEX(int N){
 
    for(int LEN = 2,num_pow = 0; LEN <= N; LEN *= 2,num_pow++){
 
        MULT[num_pow].resize(LEN/2);
 
        MULT[num_pow][0] = COMPLEX(cos(0),sin(0));
 
        COMPLEX mult = COMPLEX(cos((2*M_PI)/LEN),sin((2*M_PI)/LEN));
 
        for(int i = 1; i < LEN/2; i++){
 
            if(i%2 == 1){
                MULT[num_pow][i] = MULT[num_pow][i-1]*mult;
            }else{
                MULT[num_pow][i] = MULT[num_pow-1][i/2];
            }
        }
    }
}
 
//離散フーリエ変換
vector<COMPLEX> DFT(vector<COMPLEX> A) {
 
    int N = A.size();
 
    /*偶数項を左に、奇数項を右に仕分けるルールで要素数1まで仕分けした場合の、
     * 最終結果を先に作っておく(ビットが左右反転したものがその位置に来る)*/
    for(int i = 0; i < info.size(); i++){
 
        swap(A[info[i].left],A[info[i].right]);
    }
 
    COMPLEX a,add;
 
    for(int LEN = 2,num_pow = 0; LEN <= N; LEN *= 2,num_pow++){
 
        for(int start = 0; start < N; start += LEN){
            for(int i = 0; i < LEN/2; i++){
                //マージソートの容量で、配列を更新していく
                a = A[start+i];
                add = MULT[num_pow][i]*A[start+LEN/2+i];
 
                A[start+i] = a+add;
                A[start+LEN/2+i] = a-add;
            }
        }
    }
    return A;
}
 
//離散逆フーリエ変換
vector<COMPLEX> inverseDFT(vector<COMPLEX> A){
 
    int N = A.size();
 
    vector<COMPLEX> TMP = DFT(A);
 
    //係数を入れ替える&サイズNで各要素を割る
    vector<COMPLEX> RET(N);
 
    for(int i = 0; i < N; i++){
 
        RET[i] = TMP[(N-i)%N];
        RET[i] = RET[i]/COMPLEX(N,0);
    }
 
    return RET;
}
 
//AとBのサイズは、大きい方に揃えておく
MATRIX convolution2D(MATRIX A,MATRIX B){
 
    int SIZE = A.size();
 
    for(int i = 0; i < MAX; i++){
 
        if(SIZE == POW[i]){
            calc_swap_pair(SIZE,i);
                    break;
        }
    }
    calc_COMPLEX(SIZE);
 
    MATRIX RET(SIZE,V(SIZE));
 
    //行についてのフーリエ変換
    for(int row = 0; row < SIZE; row++){
 
        A[row] = DFT(A[row]);
        B[row] = DFT(B[row]);
    }
 
    //列についてのフーリエ変換を行単位で処理するため、転置
    for(int col = 1; col < SIZE; col++){
        for(int row = 0; row < col; row++){
            swap(A[row][col],A[col][row]);
            swap(B[row][col],B[col][row]);
        }
    }
 
    //列についてのフーリエ変換
    for(int row = 0; row < SIZE; row++){
 
        A[row] = DFT(A[row]);
        B[row] = DFT(B[row]);
    }
 
    //元に戻すため、再転置
    for(int col = 1; col < SIZE; col++){
        for(int row = 0; row < col; row++){
            swap(A[row][col],A[col][row]);
            swap(B[row][col],B[col][row]);
        }
    }
 
    //ここまでの結果を計算
    for(int row = 0; row < SIZE; row++){
        for(int col = 0; col < SIZE; col++){
 
            RET[row][col] = A[row][col]*B[row][col];
        }
    }
 
    //各行をフーリエ逆変換
    for(int row = 0; row < SIZE; row++){
 
        RET[row] = inverseDFT(RET[row]);
    }
 
    //転置
    for(int col = 1; col < SIZE; col++){
        for(int row = 0; row < col; row++){
            swap(RET[row][col],RET[col][row]);
        }
    }
 
    for(int row = 0; row < SIZE; row++){
 
        RET[row] = inverseDFT(RET[row]);
    }
 
    //元に戻すため、再転置
    for(int col = 1; col < SIZE; col++){
        for(int row = 0; row < col; row++){
            swap(RET[row][col],RET[col][row]);
        }
    }
 
    return RET;
}
 
int main(){
 
    POW[0] = 1;
    for(int i = 1; i < MAX; i++){
 
        POW[i] = POW[i-1]*2;
    }
 
    scanf("%lld %lld %lld %lld",&size_A,&size_B,&K,&L);
 
    int SIZE = 1;
    while(SIZE < size_B)SIZE *= 2;
 
    MATRIX A(SIZE,V(SIZE));
    MATRIX B(SIZE,V(SIZE));
 
    for(int row = 0; row < size_A; row++){
 
        scanf("%s",map_A[row]);
        for(int col = 0; col < size_A; col++){
 
            if(map_A[row][col] == 'X'){
                A[row][col] += 1;
            }
        }
    }
 
    scanf("%s",buf);
 
    int row = 0,col = 0;
    for(int i = 0; i < L; i++){
 
        switch(buf[i]){
        case 'U':
            row--;
            break;
        case 'D':
            row++;
            break;
        case 'L':
            col--;
            break;
        case 'R':
            col++;
            break;
        }
        B[row][col] += 1;
    }
 
    MATRIX ret = convolution2D(A,B);
 
    int ans = 0;
 
    for(int row = 0; row < SIZE; row++){
        for(int col = 0; col < SIZE; col++){
 
            if((ll)round(ret[row][col].real()) >= K)ans++;
        }
    }
 
    printf("%d\n",ans);
 
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 26768
final_rank: 7

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
using namespace std;

using ll = long long;
#define rep(i,n) for(ll i=0; i<ll(n); i++)

const int MOD = 998244353;

struct Modint {
    int x;
    Modint() : x(0) {}
    Modint(int y) : x(y%MOD) { if(x < 0) x += MOD; }
    Modint& operator+=(Modint r){ x += r.x; if(x >= MOD){ x-=MOD; } return *this; }
    Modint& operator-=(Modint r){ x -= r.x; if(x < 0){ x+=MOD; } return *this; }
    Modint& operator*=(Modint r){ x = ll(x) * r.x % MOD; return *this; }
    Modint operator+(Modint r) const { auto a = *this; a += r; return a; }
    Modint operator-(Modint r) const { auto a = *this; a -= r; return a; }
    Modint operator*(Modint r) const { auto a = *this; a *= r; return a; }
    Modint pow(ll i) const {
        Modint a = *this;
        Modint r = 1;
        while(i){
            if(i%2) r *= a;
            a *= a;
            i /= 2;
        }
        return r;
    }
    Modint inv() const { return pow(MOD-2); }
};

vector<Modint> it;

void ntt(int n, vector<Modint>& a){
    for(int h=n/2; h>=1; h/=2){
        Modint cy = 1;
        for(int s=0; s<n; s+=h*2){
            for(int t=0; t<h; t++){
                auto x = a[s+t];
                auto y = a[s+t+h];
                a[s+t] = x + y * cy;
                a[s+t+h] = x - y * cy;
            }
            cy *= it[__builtin_ctz(s / h / 2 + 1)];
        }
    }
    int j = 0;
    for(int i=1; i<n; i++){
        for(int f=n/2; f>=1; f>>=1){
            j ^= f;
            if(j&f) break;
        }
        if(i < j) swap(a[i], a[j]);
    }
}

void intt(int n, vector<Modint>& a){
    ntt(n, a);
    reverse(a.begin() + 1, a.end());
    auto q = Modint(n).inv();
    for(auto& b : a) b *= q;
}


vector<Modint> convolution(vector<Modint> a, vector<Modint> b){
    int n = a.size() + b.size() - 1;
    vector<Modint> res(n);
    int m = 1; while(m < n) m *= 2;
    a.resize(m); b.resize(m);
    ntt(m, a);
    ntt(m, b);
    rep(i,m) a[i] *= b[i];
    intt(m, a);
    rep(i,n) res[i] += a[i];
    return res;
}


void testcase(){
    int N, M, K, L; cin >> N >> M >> K >> L;
    vector<Modint> A((M-N+1)*M*4), B(N*M*4);
    auto pos = [&](ll y, ll x){ return y*M*2 + x; };
    ll y = 0, x = 0;
    rep(i,N) rep(j,N){
        char c; cin >> c;
        B[pos(i,j)] = (c == 'X' ? 1 : 0);
    }
    string s; cin >> s;
    for(char c : s){
        if(c == 'U') y--;
        if(c == 'D') y++;
        if(c == 'L') x--;
        if(c == 'R') x++;
        A[pos(y,x)] += 1;
    }
    A = convolution(A, B);
    int ans = 0;
    rep(i,M) rep(j,M) if(A[pos(i,j)].x >= K) ans += 1;
    cout << ans << "\n";
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    it.resize(23);
    it[0] = Modint(3).pow((MOD-1) / 4);
    rep(i,20) it[i+1] = Modint(3).pow((MOD-1) / (8 << i) * 3 + (MOD-1) / 2);
    testcase();
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 24432
final_rank: 6

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

template <unsigned mod = 1000000007> struct fp {
    unsigned v;
    static constexpr int get_mod() {
        return mod;
    }
    constexpr unsigned inv() const {
        assert(v != 0);
        int x = v, y = mod, p = 1, q = 0, t = 0, tmp = 0;
        while (y > 0) {
            t = x / y;
            x -= t * y, p -= t * q;
            tmp = x, x = y, y = tmp;
            tmp = p, p = q, q = tmp;
        }
        if (p < 0)
            p += mod;
        return p;
    }
    constexpr fp(ll x = 0) : v(x >= 0 ? x % mod : (mod - (-x) % mod) % mod) {}
    fp operator-() const {
        return fp() - *this;
    }
    fp pow(ull t) {
        fp res = 1, b = *this;
        while (t) {
            if (t & 1)
                res *= b;
            b *= b;
            t >>= 1;
        }
        return res;
    }
    fp &operator+=(const fp &x) {
        if ((v += x.v) >= mod)
            v -= mod;
        return *this;
    }
    fp &operator-=(const fp &x) {
        if ((v += mod - x.v) >= mod)
            v -= mod;
        return *this;
    }
    fp &operator*=(const fp &x) {
        v = ull(v) * x.v % mod;
        return *this;
    }
    fp &operator/=(const fp &x) {
        v = ull(v) * x.inv() % mod;
        return *this;
    }
    fp operator+(const fp &x) const {
        return fp(*this) += x;
    }
    fp operator-(const fp &x) const {
        return fp(*this) -= x;
    }
    fp operator*(const fp &x) const {
        return fp(*this) *= x;
    }
    fp operator/(const fp &x) const {
        return fp(*this) /= x;
    }
    bool operator==(const fp &x) const {
        return v == x.v;
    }
    bool operator!=(const fp &x) const {
        return v != x.v;
    }
    friend istream &operator>>(istream &is, fp &x) {
        return is >> x.v;
    }
    friend ostream &operator<<(ostream &os, const fp &x) {
        return os << x.v;
    }
};

// template <unsigned mod> void rd(fp<mod> &x) {
//     fastio::rd(x.v);
// }
// template <unsigned mod> void wt(fp<mod> x) {
//     fastio::wt(x.v);
// }

template <typename T> T Inv(ll n) {
    static const int md = T::get_mod();
    static vector<T> buf({0, 1});
    assert(n > 0);
    n %= md;
    while (SZ(buf) <= n) {
        int k = SZ(buf), q = (md + k - 1) / k;
        buf.push_back(buf[k * q - md] * q);
    }
    return buf[n];
}

template <typename T> T Fact(ll n, bool inv = 0) {
    static const int md = T::get_mod();
    static vector<T> buf({1, 1}), ibuf({1, 1});
    assert(n >= 0 and n < md);
    while (SZ(buf) <= n) {
        buf.push_back(buf.back() * SZ(buf));
        ibuf.push_back(ibuf.back() * Inv<T>(SZ(ibuf)));
    }
    return inv ? ibuf[n] : buf[n];
}

template <typename T> T nPr(int n, int r, bool inv = 0) {
    if (n < 0 || n < r || r < 0)
        return 0;
    return Fact<T>(n, inv) * Fact<T>(n - r, inv ^ 1);
}
template <typename T> T nCr(int n, int r, bool inv = 0) {
    if (n < 0 || n < r || r < 0)
        return 0;
    return Fact<T>(n, inv) * Fact<T>(r, inv ^ 1) * Fact<T>(n - r, inv ^ 1);
}
template <typename T> T nHr(int n, int r, bool inv = 0) {
    return nCr<T>(n + r - 1, r, inv);
}

/**
 * @brief Modint
 */

template <typename T> struct NTT {
    static constexpr int rank2 = __builtin_ctzll(T::get_mod() - 1);
    std::array<T, rank2 + 1> root;  // root[i]^(2^i) == 1

    std::array<T, rank2 + 1> iroot; // root[i] * iroot[i] == 1


    std::array<T, std::max(0, rank2 - 2 + 1)> rate2;
    std::array<T, std::max(0, rank2 - 2 + 1)> irate2;

    std::array<T, std::max(0, rank2 - 3 + 1)> rate3;
    std::array<T, std::max(0, rank2 - 3 + 1)> irate3;

    NTT() {
        T g = 2;
        while (g.pow((T::get_mod() - 1) >> 1) == 1) {
            g += 1;
        }
        root[rank2] = g.pow((T::get_mod() - 1) >> rank2);
        iroot[rank2] = root[rank2].inv();
        for (int i = rank2 - 1; i >= 0; i--) {
            root[i] = root[i + 1] * root[i + 1];
            iroot[i] = iroot[i + 1] * iroot[i + 1];
        }

        {
            T prod = 1, iprod = 1;
            for (int i = 0; i <= rank2 - 2; i++) {
                rate2[i] = root[i + 2] * prod;
                irate2[i] = iroot[i + 2] * iprod;
                prod *= iroot[i + 2];
                iprod *= root[i + 2];
            }
        }
        {
            T prod = 1, iprod = 1;
            for (int i = 0; i <= rank2 - 3; i++) {
                rate3[i] = root[i + 3] * prod;
                irate3[i] = iroot[i + 3] * iprod;
                prod *= iroot[i + 3];
                iprod *= root[i + 3];
            }
        }
    }

    void ntt(std::vector<T> &a, bool type = 0) {
        int n = int(a.size());
        int h = __builtin_ctzll((unsigned int)n);
        a.resize(1 << h);

        if (type) {
            int len = h; // a[i, i+(n>>len), i+2*(n>>len), ..] is transformed

            while (len) {
                if (len == 1) {
                    int p = 1 << (h - len);
                    T irot = 1;
                    for (int s = 0; s < (1 << (len - 1)); s++) {
                        int offset = s << (h - len + 1);
                        for (int i = 0; i < p; i++) {
                            auto l = a[i + offset];
                            auto r = a[i + offset + p];
                            a[i + offset] = l + r;
                            a[i + offset + p] =
                                (unsigned long long)(T::get_mod() + l.v - r.v) *
                                irot.v;
                            ;
                        }
                        if (s + 1 != (1 << (len - 1)))
                            irot *= irate2[__builtin_ctzll(~(unsigned int)(s))];
                    }
                    len--;
                } else {
                    // 4-base

                    int p = 1 << (h - len);
                    T irot = 1, iimag = iroot[2];
                    for (int s = 0; s < (1 << (len - 2)); s++) {
                        T irot2 = irot * irot;
                        T irot3 = irot2 * irot;
                        int offset = s << (h - len + 2);
                        for (int i = 0; i < p; i++) {
                            auto a0 = 1ULL * a[i + offset + 0 * p].v;
                            auto a1 = 1ULL * a[i + offset + 1 * p].v;
                            auto a2 = 1ULL * a[i + offset + 2 * p].v;
                            auto a3 = 1ULL * a[i + offset + 3 * p].v;

                            auto a2na3iimag =
                                1ULL * T((T::get_mod() + a2 - a3) * iimag.v).v;

                            a[i + offset] = a0 + a1 + a2 + a3;
                            a[i + offset + 1 * p] =
                                (a0 + (T::get_mod() - a1) + a2na3iimag) *
                                irot.v;
                            a[i + offset + 2 * p] =
                                (a0 + a1 + (T::get_mod() - a2) +
                                 (T::get_mod() - a3)) *
                                irot2.v;
                            a[i + offset + 3 * p] =
                                (a0 + (T::get_mod() - a1) +
                                 (T::get_mod() - a2na3iimag)) *
                                irot3.v;
                        }
                        if (s + 1 != (1 << (len - 2)))
                            irot *= irate3[__builtin_ctzll(~(unsigned int)(s))];
                    }
                    len -= 2;
                }
            }
            T e = T(n).inv();
            for (auto &x : a)
                x *= e;
        } else {
            int len = 0; // a[i, i+(n>>len), i+2*(n>>len), ..] is transformed

            while (len < h) {
                if (h - len == 1) {
                    int p = 1 << (h - len - 1);
                    T rot = 1;
                    for (int s = 0; s < (1 << len); s++) {
                        int offset = s << (h - len);
                        for (int i = 0; i < p; i++) {
                            auto l = a[i + offset];
                            auto r = a[i + offset + p] * rot;
                            a[i + offset] = l + r;
                            a[i + offset + p] = l - r;
                        }
                        if (s + 1 != (1 << len))
                            rot *= rate2[__builtin_ctzll(~(unsigned int)(s))];
                    }
                    len++;
                } else {
                    // 4-base

                    int p = 1 << (h - len - 2);
                    T rot = 1, imag = root[2];
                    for (int s = 0; s < (1 << len); s++) {
                        T rot2 = rot * rot;
                        T rot3 = rot2 * rot;
                        int offset = s << (h - len);
                        for (int i = 0; i < p; i++) {
                            auto mod2 = 1ULL * T::get_mod() * T::get_mod();
                            auto a0 = 1ULL * a[i + offset].v;
                            auto a1 = 1ULL * a[i + offset + p].v * rot.v;
                            auto a2 = 1ULL * a[i + offset + 2 * p].v * rot2.v;
                            auto a3 = 1ULL * a[i + offset + 3 * p].v * rot3.v;
                            auto a1na3imag =
                                1ULL * T(a1 + mod2 - a3).v * imag.v;
                            auto na2 = mod2 - a2;
                            a[i + offset] = a0 + a2 + a1 + a3;
                            a[i + offset + 1 * p] =
                                a0 + a2 + (2 * mod2 - (a1 + a3));
                            a[i + offset + 2 * p] = a0 + na2 + a1na3imag;
                            a[i + offset + 3 * p] =
                                a0 + na2 + (mod2 - a1na3imag);
                        }
                        if (s + 1 != (1 << len))
                            rot *= rate3[__builtin_ctzll(~(unsigned int)(s))];
                    }
                    len += 2;
                }
            }
        }
    }
    vector<T> mult(const vector<T> &a, const vector<T> &b) {
        if (a.empty() or b.empty())
            return vector<T>();
        int as = a.size(), bs = b.size();
        int n = as + bs - 1;
        if (as <= 30 or bs <= 30) {
            if (as > 30)
                return mult(b, a);
            vector<T> res(n);
            rep(i, 0, as) rep(j, 0, bs) res[i + j] += a[i] * b[j];
            return res;
        }
        int m = 1;
        while (m < n)
            m <<= 1;
        vector<T> res(m);
        rep(i, 0, as) res[i] = a[i];
        ntt(res);
        if (a == b)
            rep(i, 0, m) res[i] *= res[i];
        else {
            vector<T> c(m);
            rep(i, 0, bs) c[i] = b[i];
            ntt(c);
            rep(i, 0, m) res[i] *= c[i];
        }
        ntt(res, 1);
        res.resize(n);
        return res;
    }
};

/**
 * @brief Number Theoretic Transform
 */

template <typename T> struct Poly : vector<T> {
    Poly(int n = 0) {
        this->assign(n, T());
    }
    Poly(const initializer_list<T> f) : vector<T>::vector(f) {}
    Poly(const vector<T> &f) {
        this->assign(ALL(f));
    }
    int deg() const {
        return this->size() - 1;
    }
    T eval(const T &x) {
        T res;
        for (int i = this->size() - 1; i >= 0; i--)
            res *= x, res += this->at(i);
        return res;
    }
    Poly rev() const {
        Poly res = *this;
        reverse(ALL(res));
        return res;
    }
    void shrink() {
        while (!this->empty() and this->back() == 0)
            this->pop_back();
    }
    Poly operator>>(ll sz) const {
        if ((int)this->size() <= sz)
            return {};
        Poly ret(*this);
        ret.erase(ret.begin(), ret.begin() + sz);
        return ret;
    }
    Poly operator<<(ll sz) const {
        Poly ret(*this);
        ret.insert(ret.begin(), sz, T(0));
        return ret;
    }
    Poly<T> mult(const Poly<T> &a, const Poly<T> &b) {
        if (a.empty() or b.empty())
            return {};
        int as = a.size(), bs = b.size();
        int n = as + bs - 1;
        if (as <= 30 or bs <= 30) {
            if (as > 30)
                return mult(b, a);
            Poly<T> res(n);
            rep(i, 0, as) rep(j, 0, bs) res[i + j] += a[i] * b[j];
            return res;
        }
        int m = 1;
        while (m < n)
            m <<= 1;
        Poly<T> res(m);
        rep(i, 0, as) res[i] = a[i];
        res.NTT(0);
        if (a == b)
            rep(i, 0, m) res[i] *= res[i];
        else {
            Poly<T> c(m);
            rep(i, 0, bs) c[i] = b[i];
            c.NTT(0);
            rep(i, 0, m) res[i] *= c[i];
        }
        res.NTT(1);
        res.resize(n);
        return res;
    }
    Poly square() const {
        return Poly(mult(*this, *this));
    }
    Poly operator-() const {
        return Poly() - *this;
    }
    Poly operator+(const Poly &g) const {
        return Poly(*this) += g;
    }
    Poly operator+(const T &g) const {
        return Poly(*this) += g;
    }
    Poly operator-(const Poly &g) const {
        return Poly(*this) -= g;
    }
    Poly operator-(const T &g) const {
        return Poly(*this) -= g;
    }
    Poly operator*(const Poly &g) const {
        return Poly(*this) *= g;
    }
    Poly operator*(const T &g) const {
        return Poly(*this) *= g;
    }
    Poly operator/(const Poly &g) const {
        return Poly(*this) /= g;
    }
    Poly operator/(const T &g) const {
        return Poly(*this) /= g;
    }
    Poly operator%(const Poly &g) const {
        return Poly(*this) %= g;
    }
    pair<Poly, Poly> divmod(const Poly &g) const {
        Poly q = *this / g, r = *this - g * q;
        r.shrink();
        return {q, r};
    }
    Poly &operator+=(const Poly &g) {
        if (g.size() > this->size())
            this->resize(g.size());
        rep(i, 0, g.size()) {
            (*this)[i] += g[i];
        }
        return *this;
    }
    Poly &operator+=(const T &g) {
        if (this->empty())
            this->push_back(0);
        (*this)[0] += g;
        return *this;
    }
    Poly &operator-=(const Poly &g) {
        if (g.size() > this->size())
            this->resize(g.size());
        rep(i, 0, g.size()) {
            (*this)[i] -= g[i];
        }
        return *this;
    }
    Poly &operator-=(const T &g) {
        if (this->empty())
            this->push_back(0);
        (*this)[0] -= g;
        return *this;
    }
    Poly &operator*=(const Poly &g) {
        *this = mult(*this, g);
        return *this;
    }
    Poly &operator*=(const T &g) {
        rep(i, 0, this->size())(*this)[i] *= g;
        return *this;
    }
    Poly &operator/=(const Poly &g) {
        if (g.size() > this->size()) {
            this->clear();
            return *this;
        }
        Poly g2 = g;
        reverse(ALL(*this));
        reverse(ALL(g2));
        int n = this->size() - g2.size() + 1;
        this->resize(n);
        g2.resize(n);
        *this *= g2.inv();
        this->resize(n);
        reverse(ALL(*this));
        shrink();
        return *this;
    }
    Poly &operator/=(const T &g) {
        rep(i, 0, this->size())(*this)[i] /= g;
        return *this;
    }
    Poly &operator%=(const Poly &g) {
        *this -= *this / g * g;
        shrink();
        return *this;
    }
    Poly diff() const {
        Poly res(this->size() - 1);
        rep(i, 0, res.size()) res[i] = (*this)[i + 1] * (i + 1);
        return res;
    }
    Poly inte() const {
        Poly res(this->size() + 1);
        for (int i = res.size() - 1; i; i--)
            res[i] = (*this)[i - 1] / i;
        return res;
    }
    Poly log() const {
        assert(this->front() == 1);
        const int n = this->size();
        Poly res = diff() * inv();
        res = res.inte();
        res.resize(n);
        return res;
    }
    Poly shift(const int &c) const {
        const int n = this->size();
        Poly res = *this, g(n);
        g[0] = 1;
        rep(i, 1, n) g[i] = g[i - 1] * c / i;
        vector<T> fact(n, 1);
        rep(i, 0, n) {
            if (i)
                fact[i] = fact[i - 1] * i;
            res[i] *= fact[i];
        }
        res = res.rev();
        res *= g;
        res.resize(n);
        res = res.rev();
        rep(i, 0, n) res[i] /= fact[i];
        return res;
    }
    Poly inv() const {
        const int n = this->size();
        Poly res(1);
        res.front() = T(1) / this->front();
        for (int k = 1; k < n; k <<= 1) {
            Poly f(k * 2), g(k * 2);
            rep(i, 0, min(n, k * 2)) f[i] = (*this)[i];
            rep(i, 0, k) g[i] = res[i];
            f.NTT(0);
            g.NTT(0);
            rep(i, 0, k * 2) f[i] *= g[i];
            f.NTT(1);
            rep(i, 0, k) {
                f[i] = 0;
                f[i + k] = -f[i + k];
            }
            f.NTT(0);
            rep(i, 0, k * 2) f[i] *= g[i];
            f.NTT(1);
            rep(i, 0, k) f[i] = res[i];
            swap(res, f);
        }
        res.resize(n);
        return res;
    }
    Poly exp() const {
        const int n = this->size();
        if (n == 1)
            return Poly({T(1)});
        Poly b(2), c(1), z1, z2(2);
        b[0] = c[0] = z2[0] = z2[1] = 1;
        b[1] = (*this)[1];
        for (int k = 2; k < n; k <<= 1) {
            Poly y = b;
            y.resize(k * 2);
            y.NTT(0);
            z1 = z2;
            Poly z(k);
            rep(i, 0, k) z[i] = y[i] * z1[i];
            z.NTT(1);
            rep(i, 0, k >> 1) z[i] = 0;
            z.NTT(0);
            rep(i, 0, k) z[i] *= -z1[i];
            z.NTT(1);
            c.insert(c.end(), z.begin() + (k >> 1), z.end());
            z2 = c;
            z2.resize(k * 2);
            z2.NTT(0);
            Poly x = *this;
            x.resize(k);
            x = x.diff();
            x.resize(k);
            x.NTT(0);
            rep(i, 0, k) x[i] *= y[i];
            x.NTT(1);
            Poly bb = b.diff();
            rep(i, 0, k - 1) x[i] -= bb[i];
            x.resize(k * 2);
            rep(i, 0, k - 1) {
                x[k + i] = x[i];
                x[i] = 0;
            }
            x.NTT(0);
            rep(i, 0, k * 2) x[i] *= z2[i];
            x.NTT(1);
            x.pop_back();
            x = x.inte();
            rep(i, k, min(n, k * 2)) x[i] += (*this)[i];
            rep(i, 0, k) x[i] = 0;
            x.NTT(0);
            rep(i, 0, k * 2) x[i] *= y[i];
            x.NTT(1);
            b.insert(b.end(), x.begin() + k, x.end());
        }
        b.resize(n);
        return b;
    }
    Poly pow(ll t) {
        if (t == 0) {
            Poly res(this->size());
            res[0] = 1;
            return res;
        }
        int n = this->size(), k = 0;
        while (k < n and (*this)[k] == 0)
            k++;
        Poly res(n);
        if (__int128_t(t) * k >= n)
            return res;
        n -= t * k;
        Poly g(n);
        T c = (*this)[k], ic = c.inv();
        rep(i, 0, n) g[i] = (*this)[i + k] * ic;
        g = g.log();
        for (auto &x : g)
            x *= t;
        g = g.exp();
        c = c.pow(t);
        rep(i, 0, n) res[i + t * k] = g[i] * c;
        return res;
    }
    void NTT(bool inv);
};

/**
 * @brief Formal Power Series (NTT-friendly mod)
 */

using Fp = fp<998244353>;

NTT<Fp> ntt;
template <> void Poly<Fp>::NTT(bool inv) {
    ntt.ntt(*this, inv);
}

int main() {
    cin.tie(0);
    ios_base::sync_with_stdio(false);
    int N, M, K, L;
    cin >> N >> M >> K >> L;
    Poly<Fp> A(M*M), B(M*M);
    rep(i,0,N) {
        rep(j,0,N) {
            char c;
            cin >> c;
            if (c == 'X') A[i*M+j]+=1;
        }
    }
    string S;
    cin >> S;
    int CX = 0, CY = 0;
    rep(i,0,L) {
        if (S[i] == 'D') CX++;
        if (S[i] == 'U') CX--;
        if (S[i] == 'R') CY++;
        if (S[i] == 'L') CY--;
        B[CX*M+CY]+=1;
    }
    auto C = A*B;
    int ANS = 0;
    rep(i,0,M*M) if (C[i].v >= K) ANS++;
    cout << ANS << '\n';
}
accuracy: 1
time_ms: 20
memory_kb: 10544
final_rank: 3

code_snippet: #line 1 "library/Template/template.hpp"
#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}
#line 2 "library/Utility/fastio.hpp"
#include <unistd.h>
namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf

uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio

using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */
#line 3 "sol.cpp"

#line 2 "library/Math/modint.hpp"

template <unsigned mod = 1000000007> struct fp {
    unsigned v;
    static constexpr int get_mod() {
        return mod;
    }
    constexpr unsigned inv() const {
        assert(v != 0);
        int x = v, y = mod, p = 1, q = 0, t = 0, tmp = 0;
        while (y > 0) {
            t = x / y;
            x -= t * y, p -= t * q;
            tmp = x, x = y, y = tmp;
            tmp = p, p = q, q = tmp;
        }
        if (p < 0)
            p += mod;
        return p;
    }
    constexpr fp(ll x = 0) : v(x >= 0 ? x % mod : (mod - (-x) % mod) % mod) {}
    fp operator-() const {
        return fp() - *this;
    }
    fp pow(ull t) {
        fp res = 1, b = *this;
        while (t) {
            if (t & 1)
                res *= b;
            b *= b;
            t >>= 1;
        }
        return res;
    }
    fp &operator+=(const fp &x) {
        if ((v += x.v) >= mod)
            v -= mod;
        return *this;
    }
    fp &operator-=(const fp &x) {
        if ((v += mod - x.v) >= mod)
            v -= mod;
        return *this;
    }
    fp &operator*=(const fp &x) {
        v = ull(v) * x.v % mod;
        return *this;
    }
    fp &operator/=(const fp &x) {
        v = ull(v) * x.inv() % mod;
        return *this;
    }
    fp operator+(const fp &x) const {
        return fp(*this) += x;
    }
    fp operator-(const fp &x) const {
        return fp(*this) -= x;
    }
    fp operator*(const fp &x) const {
        return fp(*this) *= x;
    }
    fp operator/(const fp &x) const {
        return fp(*this) /= x;
    }
    bool operator==(const fp &x) const {
        return v == x.v;
    }
    bool operator!=(const fp &x) const {
        return v != x.v;
    }
    friend istream &operator>>(istream &is, fp &x) {
        return is >> x.v;
    }
    friend ostream &operator<<(ostream &os, const fp &x) {
        return os << x.v;
    }
};

template <unsigned mod> void rd(fp<mod> &x) {
    fastio::rd(x.v);
}
template <unsigned mod> void wt(fp<mod> x) {
    fastio::wt(x.v);
}

template <typename T> T Inv(ll n) {
    static const int md = T::get_mod();
    static vector<T> buf({0, 1});
    assert(n > 0);
    n %= md;
    while (SZ(buf) <= n) {
        int k = SZ(buf), q = (md + k - 1) / k;
        buf.push_back(buf[k * q - md] * q);
    }
    return buf[n];
}

template <typename T> T Fact(ll n, bool inv = 0) {
    static const int md = T::get_mod();
    static vector<T> buf({1, 1}), ibuf({1, 1});
    assert(n >= 0 and n < md);
    while (SZ(buf) <= n) {
        buf.push_back(buf.back() * SZ(buf));
        ibuf.push_back(ibuf.back() * Inv<T>(SZ(ibuf)));
    }
    return inv ? ibuf[n] : buf[n];
}

template <typename T> T nPr(int n, int r, bool inv = 0) {
    if (n < 0 || n < r || r < 0)
        return 0;
    return Fact<T>(n, inv) * Fact<T>(n - r, inv ^ 1);
}
template <typename T> T nCr(int n, int r, bool inv = 0) {
    if (n < 0 || n < r || r < 0)
        return 0;
    return Fact<T>(n, inv) * Fact<T>(r, inv ^ 1) * Fact<T>(n - r, inv ^ 1);
}
template <typename T> T nHr(int n, int r, bool inv = 0) {
    return nCr<T>(n + r - 1, r, inv);
}

/**
 * @brief Modint
 */
#line 2 "library/Convolution/ntt.hpp"

template <typename T> struct NTT {
    static constexpr int rank2 = __builtin_ctzll(T::get_mod() - 1);
    std::array<T, rank2 + 1> root;  // root[i]^(2^i) == 1
    std::array<T, rank2 + 1> iroot; // root[i] * iroot[i] == 1

    std::array<T, std::max(0, rank2 - 2 + 1)> rate2;
    std::array<T, std::max(0, rank2 - 2 + 1)> irate2;

    std::array<T, std::max(0, rank2 - 3 + 1)> rate3;
    std::array<T, std::max(0, rank2 - 3 + 1)> irate3;

    NTT() {
        T g = 2;
        while (g.pow((T::get_mod() - 1) >> 1) == 1) {
            g += 1;
        }
        root[rank2] = g.pow((T::get_mod() - 1) >> rank2);
        iroot[rank2] = root[rank2].inv();
        for (int i = rank2 - 1; i >= 0; i--) {
            root[i] = root[i + 1] * root[i + 1];
            iroot[i] = iroot[i + 1] * iroot[i + 1];
        }

        {
            T prod = 1, iprod = 1;
            for (int i = 0; i <= rank2 - 2; i++) {
                rate2[i] = root[i + 2] * prod;
                irate2[i] = iroot[i + 2] * iprod;
                prod *= iroot[i + 2];
                iprod *= root[i + 2];
            }
        }
        {
            T prod = 1, iprod = 1;
            for (int i = 0; i <= rank2 - 3; i++) {
                rate3[i] = root[i + 3] * prod;
                irate3[i] = iroot[i + 3] * iprod;
                prod *= iroot[i + 3];
                iprod *= root[i + 3];
            }
        }
    }

    void ntt(std::vector<T> &a, bool type = 0) {
        int n = int(a.size());
        int h = __builtin_ctzll((unsigned int)n);
        a.resize(1 << h);

        if (type) {
            int len = h; // a[i, i+(n>>len), i+2*(n>>len), ..] is transformed
            while (len) {
                if (len == 1) {
                    int p = 1 << (h - len);
                    T irot = 1;
                    for (int s = 0; s < (1 << (len - 1)); s++) {
                        int offset = s << (h - len + 1);
                        for (int i = 0; i < p; i++) {
                            auto l = a[i + offset];
                            auto r = a[i + offset + p];
                            a[i + offset] = l + r;
                            a[i + offset + p] =
                                (unsigned long long)(T::get_mod() + l.v - r.v) *
                                irot.v;
                            ;
                        }
                        if (s + 1 != (1 << (len - 1)))
                            irot *= irate2[__builtin_ctzll(~(unsigned int)(s))];
                    }
                    len--;
                } else {
                    // 4-base
                    int p = 1 << (h - len);
                    T irot = 1, iimag = iroot[2];
                    for (int s = 0; s < (1 << (len - 2)); s++) {
                        T irot2 = irot * irot;
                        T irot3 = irot2 * irot;
                        int offset = s << (h - len + 2);
                        for (int i = 0; i < p; i++) {
                            auto a0 = 1ULL * a[i + offset + 0 * p].v;
                            auto a1 = 1ULL * a[i + offset + 1 * p].v;
                            auto a2 = 1ULL * a[i + offset + 2 * p].v;
                            auto a3 = 1ULL * a[i + offset + 3 * p].v;

                            auto a2na3iimag =
                                1ULL * T((T::get_mod() + a2 - a3) * iimag.v).v;

                            a[i + offset] = a0 + a1 + a2 + a3;
                            a[i + offset + 1 * p] =
                                (a0 + (T::get_mod() - a1) + a2na3iimag) *
                                irot.v;
                            a[i + offset + 2 * p] =
                                (a0 + a1 + (T::get_mod() - a2) +
                                 (T::get_mod() - a3)) *
                                irot2.v;
                            a[i + offset + 3 * p] =
                                (a0 + (T::get_mod() - a1) +
                                 (T::get_mod() - a2na3iimag)) *
                                irot3.v;
                        }
                        if (s + 1 != (1 << (len - 2)))
                            irot *= irate3[__builtin_ctzll(~(unsigned int)(s))];
                    }
                    len -= 2;
                }
            }
            T e = T(n).inv();
            for (auto &x : a)
                x *= e;
        } else {
            int len = 0; // a[i, i+(n>>len), i+2*(n>>len), ..] is transformed
            while (len < h) {
                if (h - len == 1) {
                    int p = 1 << (h - len - 1);
                    T rot = 1;
                    for (int s = 0; s < (1 << len); s++) {
                        int offset = s << (h - len);
                        for (int i = 0; i < p; i++) {
                            auto l = a[i + offset];
                            auto r = a[i + offset + p] * rot;
                            a[i + offset] = l + r;
                            a[i + offset + p] = l - r;
                        }
                        if (s + 1 != (1 << len))
                            rot *= rate2[__builtin_ctzll(~(unsigned int)(s))];
                    }
                    len++;
                } else {
                    // 4-base
                    int p = 1 << (h - len - 2);
                    T rot = 1, imag = root[2];
                    for (int s = 0; s < (1 << len); s++) {
                        T rot2 = rot * rot;
                        T rot3 = rot2 * rot;
                        int offset = s << (h - len);
                        for (int i = 0; i < p; i++) {
                            auto mod2 = 1ULL * T::get_mod() * T::get_mod();
                            auto a0 = 1ULL * a[i + offset].v;
                            auto a1 = 1ULL * a[i + offset + p].v * rot.v;
                            auto a2 = 1ULL * a[i + offset + 2 * p].v * rot2.v;
                            auto a3 = 1ULL * a[i + offset + 3 * p].v * rot3.v;
                            auto a1na3imag =
                                1ULL * T(a1 + mod2 - a3).v * imag.v;
                            auto na2 = mod2 - a2;
                            a[i + offset] = a0 + a2 + a1 + a3;
                            a[i + offset + 1 * p] =
                                a0 + a2 + (2 * mod2 - (a1 + a3));
                            a[i + offset + 2 * p] = a0 + na2 + a1na3imag;
                            a[i + offset + 3 * p] =
                                a0 + na2 + (mod2 - a1na3imag);
                        }
                        if (s + 1 != (1 << len))
                            rot *= rate3[__builtin_ctzll(~(unsigned int)(s))];
                    }
                    len += 2;
                }
            }
        }
    }
    vector<T> mult(const vector<T> &a, const vector<T> &b) {
        if (a.empty() or b.empty())
            return vector<T>();
        int as = a.size(), bs = b.size();
        int n = as + bs - 1;
        if (as <= 30 or bs <= 30) {
            if (as > 30)
                return mult(b, a);
            vector<T> res(n);
            rep(i, 0, as) rep(j, 0, bs) res[i + j] += a[i] * b[j];
            return res;
        }
        int m = 1;
        while (m < n)
            m <<= 1;
        vector<T> res(m);
        rep(i, 0, as) res[i] = a[i];
        ntt(res);
        if (a == b)
            rep(i, 0, m) res[i] *= res[i];
        else {
            vector<T> c(m);
            rep(i, 0, bs) c[i] = b[i];
            ntt(c);
            rep(i, 0, m) res[i] *= c[i];
        }
        ntt(res, 1);
        res.resize(n);
        return res;
    }
};

/**
 * @brief Number Theoretic Transform
 */
#line 6 "sol.cpp"
using Fp = fp<998244353>;
NTT<Fp> ntt;

int main() {
    int n, m, k, l;
    read(n, m, k, l);
    vector<string> s(n);
    read(s);
    string t;
    read(t);

    const int N = 1010;
    vector<Fp> a(N * N), b(N * N);
    rep(i, 0, n) rep(j, 0, n) if (s[i][j] == 'X') {
        a[i * N + j] = 1;
    }
    int x = 0, y = 0;
    for (auto &c : t) {
        if (c == 'L')
            y--;
        if (c == 'R')
            y++;
        if (c == 'D')
            x++;
        if (c == 'U')
            x--;
        b[x * N + y] += 1;
    }
    auto c = ntt.mult(a, b);
    int ret = 0;
    for (auto &x : c)
        if (x.v >= k)
            ret++;
    print(ret);
    return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 28380
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll=long long;


#include <algorithm>
#include <array>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

// @param n `0 <= n`
// @return minimum non-negative `x` s.t. `n <= 2**x`
int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n)) x++;
    return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
int bsf(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

}  // namespace internal

}  // namespace atcoder



#include <utility>

namespace atcoder {

namespace internal {

// @param m `1 <= m`
// @return x mod m
constexpr long long safe_mod(long long x, long long m) {
    x %= m;
    if (x < 0) x += m;
    return x;
}

// Fast modular multiplication by barrett reduction
// Reference: https://en.wikipedia.org/wiki/Barrett_reduction
// NOTE: reconsider after Ice Lake
struct barrett {
    unsigned int _m;
    unsigned long long im;

    // @param m `1 <= m < 2^31`
    barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}

    // @return m
    unsigned int umod() const { return _m; }

    // @param a `0 <= a < m`
    // @param b `0 <= b < m`
    // @return `a * b % m`
    unsigned int mul(unsigned int a, unsigned int b) const {
        // [1] m = 1
        // a = b = im = 0, so okay

        // [2] m >= 2
        // im = ceil(2^64 / m)
        // -> im * m = 2^64 + r (0 <= r < m)
        // let z = a*b = c*m + d (0 <= c, d < m)
        // a*b * im = (c*m + d) * im = c*(im*m) + d*im = c*2^64 + c*r + d*im
        // c*r + d*im < m * m + m * im < m * m + 2^64 + m <= 2^64 + m * (m + 1) < 2^64 * 2
        // ((ab * im) >> 64) == c or c + 1
        unsigned long long z = a;
        z *= b;
#ifdef _MSC_VER
        unsigned long long x;
        _umul128(z, im, &x);
#else
        unsigned long long x =
            (unsigned long long)(((unsigned __int128)(z)*im) >> 64);
#endif
        unsigned int v = (unsigned int)(z - x * _m);
        if (_m <= v) v += _m;
        return v;
    }
};

// @param n `0 <= n`
// @param m `1 <= m`
// @return `(x ** n) % m`
constexpr long long pow_mod_constexpr(long long x, long long n, int m) {
    if (m == 1) return 0;
    unsigned int _m = (unsigned int)(m);
    unsigned long long r = 1;
    unsigned long long y = safe_mod(x, m);
    while (n) {
        if (n & 1) r = (r * y) % _m;
        y = (y * y) % _m;
        n >>= 1;
    }
    return r;
}

// Reference:
// M. Forisek and J. Jancina,
// Fast Primality Testing for Integers That Fit into a Machine Word
// @param n `0 <= n`
constexpr bool is_prime_constexpr(int n) {
    if (n <= 1) return false;
    if (n == 2 || n == 7 || n == 61) return true;
    if (n % 2 == 0) return false;
    long long d = n - 1;
    while (d % 2 == 0) d /= 2;
    constexpr long long bases[3] = {2, 7, 61};
    for (long long a : bases) {
        long long t = d;
        long long y = pow_mod_constexpr(a, t, n);
        while (t != n - 1 && y != 1 && y != n - 1) {
            y = y * y % n;
            t <<= 1;
        }
        if (y != n - 1 && t % 2 == 0) {
            return false;
        }
    }
    return true;
}
template <int n> constexpr bool is_prime = is_prime_constexpr(n);

// @param b `1 <= b`
// @return pair(g, x) s.t. g = gcd(a, b), xa = g (mod b), 0 <= x < b/g
constexpr std::pair<long long, long long> inv_gcd(long long a, long long b) {
    a = safe_mod(a, b);
    if (a == 0) return {b, 0};

    // Contracts:
    // [1] s - m0 * a = 0 (mod b)
    // [2] t - m1 * a = 0 (mod b)
    // [3] s * |m1| + t * |m0| <= b
    long long s = b, t = a;
    long long m0 = 0, m1 = 1;

    while (t) {
        long long u = s / t;
        s -= t * u;
        m0 -= m1 * u;  // |m1 * u| <= |m1| * s <= b

        // [3]:
        // (s - t * u) * |m1| + t * |m0 - m1 * u|
        // <= s * |m1| - t * u * |m1| + t * (|m0| + |m1| * u)
        // = s * |m1| + t * |m0| <= b

        auto tmp = s;
        s = t;
        t = tmp;
        tmp = m0;
        m0 = m1;
        m1 = tmp;
    }
    // by [3]: |m0| <= b/g
    // by g != b: |m0| < b/g
    if (m0 < 0) m0 += b / s;
    return {s, m0};
}

// Compile time primitive root
// @param m must be prime
// @return primitive root (and minimum in now)
constexpr int primitive_root_constexpr(int m) {
    if (m == 2) return 1;
    if (m == 167772161) return 3;
    if (m == 469762049) return 3;
    if (m == 754974721) return 11;
    if (m == 998244353) return 3;
    int divs[20] = {};
    divs[0] = 2;
    int cnt = 1;
    int x = (m - 1) / 2;
    while (x % 2 == 0) x /= 2;
    for (int i = 3; (long long)(i)*i <= x; i += 2) {
        if (x % i == 0) {
            divs[cnt++] = i;
            while (x % i == 0) {
                x /= i;
            }
        }
    }
    if (x > 1) {
        divs[cnt++] = x;
    }
    for (int g = 2;; g++) {
        bool ok = true;
        for (int i = 0; i < cnt; i++) {
            if (pow_mod_constexpr(g, (m - 1) / divs[i], m) == 1) {
                ok = false;
                break;
            }
        }
        if (ok) return g;
    }
}
template <int m> constexpr int primitive_root = primitive_root_constexpr(m);

}  // namespace internal

}  // namespace atcoder


#include <cassert>
#include <numeric>
#include <type_traits>

namespace atcoder {

namespace internal {

#ifndef _MSC_VER
template <class T>
using is_signed_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value ||
                                  std::is_same<T, __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int128 =
    typename std::conditional<std::is_same<T, __uint128_t>::value ||
                                  std::is_same<T, unsigned __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using make_unsigned_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value,
                              __uint128_t,
                              unsigned __int128>;

template <class T>
using is_integral = typename std::conditional<std::is_integral<T>::value ||
                                                  is_signed_int128<T>::value ||
                                                  is_unsigned_int128<T>::value,
                                              std::true_type,
                                              std::false_type>::type;

template <class T>
using is_signed_int = typename std::conditional<(is_integral<T>::value &&
                                                 std::is_signed<T>::value) ||
                                                    is_signed_int128<T>::value,
                                                std::true_type,
                                                std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<(is_integral<T>::value &&
                               std::is_unsigned<T>::value) ||
                                  is_unsigned_int128<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<
    is_signed_int128<T>::value,
    make_unsigned_int128<T>,
    typename std::conditional<std::is_signed<T>::value,
                              std::make_unsigned<T>,
                              std::common_type<T>>::type>::type;

#else

template <class T> using is_integral = typename std::is_integral<T>;

template <class T>
using is_signed_int =
    typename std::conditional<is_integral<T>::value && std::is_signed<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<is_integral<T>::value &&
                                  std::is_unsigned<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<is_signed_int<T>::value,
                                              std::make_unsigned<T>,
                                              std::common_type<T>>::type;

#endif

template <class T>
using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;

template <class T>
using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;

template <class T> using to_unsigned_t = typename to_unsigned<T>::type;

}  // namespace internal

}  // namespace atcoder

#include <cassert>
#include <numeric>
#include <type_traits>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

struct modint_base {};
struct static_modint_base : modint_base {};

template <class T> using is_modint = std::is_base_of<modint_base, T>;
template <class T> using is_modint_t = std::enable_if_t<is_modint<T>::value>;

}  // namespace internal

template <int m, std::enable_if_t<(1 <= m)>* = nullptr>
struct static_modint : internal::static_modint_base {
    using mint = static_modint;

  public:
    static constexpr int mod() { return m; }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    static_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    static_modint(T v) {
        long long x = (long long)(v % (long long)(umod()));
        if (x < 0) x += umod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    static_modint(T v) {
        _v = (unsigned int)(v % umod());
    }
    static_modint(bool v) { _v = ((unsigned int)(v) % umod()); }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v -= rhs._v;
        if (_v >= umod()) _v += umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        unsigned long long z = _v;
        z *= rhs._v;
        _v = (unsigned int)(z % umod());
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        if (prime) {
            assert(_v);
            return pow(umod() - 2);
        } else {
            auto eg = internal::inv_gcd(_v, m);
            assert(eg.first == 1);
            return eg.second;
        }
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static constexpr unsigned int umod() { return m; }
    static constexpr bool prime = internal::is_prime<m>;
};

template <int id> struct dynamic_modint : internal::modint_base {
    using mint = dynamic_modint;

  public:
    static int mod() { return (int)(bt.umod()); }
    static void set_mod(int m) {
        assert(1 <= m);
        bt = internal::barrett(m);
    }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    dynamic_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        long long x = (long long)(v % (long long)(mod()));
        if (x < 0) x += mod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        _v = (unsigned int)(v % mod());
    }
    dynamic_modint(bool v) { _v = ((unsigned int)(v) % mod()); }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v += mod() - rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        _v = bt.mul(_v, rhs._v);
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        auto eg = internal::inv_gcd(_v, mod());
        assert(eg.first == 1);
        return eg.second;
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static internal::barrett bt;
    static unsigned int umod() { return bt.umod(); }
};
template <int id> internal::barrett dynamic_modint<id>::bt = 998244353;

using modint998244353 = static_modint<998244353>;
using modint1000000007 = static_modint<1000000007>;
using modint = dynamic_modint<-1>;

namespace internal {

template <class T>
using is_static_modint = std::is_base_of<internal::static_modint_base, T>;

template <class T>
using is_static_modint_t = std::enable_if_t<is_static_modint<T>::value>;

template <class> struct is_dynamic_modint : public std::false_type {};
template <int id>
struct is_dynamic_modint<dynamic_modint<id>> : public std::true_type {};

template <class T>
using is_dynamic_modint_t = std::enable_if_t<is_dynamic_modint<T>::value>;

}  // namespace internal

}  // namespace atcoder

#include <cassert>
#include <type_traits>
#include <vector>

namespace atcoder {

namespace internal {

template <class mint, internal::is_static_modint_t<mint>* = nullptr>
void butterfly(std::vector<mint>& a) {
    static constexpr int g = internal::primitive_root<mint::mod()>;
    int n = int(a.size());
    int h = internal::ceil_pow2(n);

    static bool first = true;
    static mint sum_e[30];  // sum_e[i] = ies[0] * ... * ies[i - 1] * es[i]
    if (first) {
        first = false;
        mint es[30], ies[30];  // es[i]^(2^(2+i)) == 1
        int cnt2 = bsf(mint::mod() - 1);
        mint e = mint(g).pow((mint::mod() - 1) >> cnt2), ie = e.inv();
        for (int i = cnt2; i >= 2; i--) {
            // e^(2^i) == 1
            es[i - 2] = e;
            ies[i - 2] = ie;
            e *= e;
            ie *= ie;
        }
        mint now = 1;
        for (int i = 0; i <= cnt2 - 2; i++) {
            sum_e[i] = es[i] * now;
            now *= ies[i];
        }
    }
    for (int ph = 1; ph <= h; ph++) {
        int w = 1 << (ph - 1), p = 1 << (h - ph);
        mint now = 1;
        for (int s = 0; s < w; s++) {
            int offset = s << (h - ph + 1);
            for (int i = 0; i < p; i++) {
                auto l = a[i + offset];
                auto r = a[i + offset + p] * now;
                a[i + offset] = l + r;
                a[i + offset + p] = l - r;
            }
            now *= sum_e[bsf(~(unsigned int)(s))];
        }
    }
}

template <class mint, internal::is_static_modint_t<mint>* = nullptr>
void butterfly_inv(std::vector<mint>& a) {
    static constexpr int g = internal::primitive_root<mint::mod()>;
    int n = int(a.size());
    int h = internal::ceil_pow2(n);

    static bool first = true;
    static mint sum_ie[30];  // sum_ie[i] = es[0] * ... * es[i - 1] * ies[i]
    if (first) {
        first = false;
        mint es[30], ies[30];  // es[i]^(2^(2+i)) == 1
        int cnt2 = bsf(mint::mod() - 1);
        mint e = mint(g).pow((mint::mod() - 1) >> cnt2), ie = e.inv();
        for (int i = cnt2; i >= 2; i--) {
            // e^(2^i) == 1
            es[i - 2] = e;
            ies[i - 2] = ie;
            e *= e;
            ie *= ie;
        }
        mint now = 1;
        for (int i = 0; i <= cnt2 - 2; i++) {
            sum_ie[i] = ies[i] * now;
            now *= es[i];
        }
    }

    for (int ph = h; ph >= 1; ph--) {
        int w = 1 << (ph - 1), p = 1 << (h - ph);
        mint inow = 1;
        for (int s = 0; s < w; s++) {
            int offset = s << (h - ph + 1);
            for (int i = 0; i < p; i++) {
                auto l = a[i + offset];
                auto r = a[i + offset + p];
                a[i + offset] = l + r;
                a[i + offset + p] =
                    (unsigned long long)(mint::mod() + l.val() - r.val()) *
                    inow.val();
            }
            inow *= sum_ie[bsf(~(unsigned int)(s))];
        }
    }
}

}  // namespace internal

template <class mint, internal::is_static_modint_t<mint>* = nullptr>
std::vector<mint> convolution(std::vector<mint> a, std::vector<mint> b) {
    int n = int(a.size()), m = int(b.size());
    if (!n || !m) return {};
    if (std::min(n, m) <= 60) {
        if (n < m) {
            std::swap(n, m);
            std::swap(a, b);
        }
        std::vector<mint> ans(n + m - 1);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                ans[i + j] += a[i] * b[j];
            }
        }
        return ans;
    }
    int z = 1 << internal::ceil_pow2(n + m - 1);
    a.resize(z);
    internal::butterfly(a);
    b.resize(z);
    internal::butterfly(b);
    for (int i = 0; i < z; i++) {
        a[i] *= b[i];
    }
    internal::butterfly_inv(a);
    a.resize(n + m - 1);
    mint iz = mint(z).inv();
    for (int i = 0; i < n + m - 1; i++) a[i] *= iz;
    return a;
}

template <unsigned int mod = 998244353,
          class T,
          std::enable_if_t<internal::is_integral<T>::value>* = nullptr>
std::vector<T> convolution(const std::vector<T>& a, const std::vector<T>& b) {
    int n = int(a.size()), m = int(b.size());
    if (!n || !m) return {};

    using mint = static_modint<mod>;
    std::vector<mint> a2(n), b2(m);
    for (int i = 0; i < n; i++) {
        a2[i] = mint(a[i]);
    }
    for (int i = 0; i < m; i++) {
        b2[i] = mint(b[i]);
    }
    auto c2 = convolution(move(a2), move(b2));
    std::vector<T> c(n + m - 1);
    for (int i = 0; i < n + m - 1; i++) {
        c[i] = c2[i].val();
    }
    return c;
}

std::vector<long long> convolution_ll(const std::vector<long long>& a,
                                      const std::vector<long long>& b) {
    int n = int(a.size()), m = int(b.size());
    if (!n || !m) return {};

    static constexpr unsigned long long MOD1 = 754974721;  // 2^24
    static constexpr unsigned long long MOD2 = 167772161;  // 2^25
    static constexpr unsigned long long MOD3 = 469762049;  // 2^26
    static constexpr unsigned long long M2M3 = MOD2 * MOD3;
    static constexpr unsigned long long M1M3 = MOD1 * MOD3;
    static constexpr unsigned long long M1M2 = MOD1 * MOD2;
    static constexpr unsigned long long M1M2M3 = MOD1 * MOD2 * MOD3;

    static constexpr unsigned long long i1 =
        internal::inv_gcd(MOD2 * MOD3, MOD1).second;
    static constexpr unsigned long long i2 =
        internal::inv_gcd(MOD1 * MOD3, MOD2).second;
    static constexpr unsigned long long i3 =
        internal::inv_gcd(MOD1 * MOD2, MOD3).second;

    auto c1 = convolution<MOD1>(a, b);
    auto c2 = convolution<MOD2>(a, b);
    auto c3 = convolution<MOD3>(a, b);

    std::vector<long long> c(n + m - 1);
    for (int i = 0; i < n + m - 1; i++) {
        unsigned long long x = 0;
        x += (c1[i] * i1) % MOD1 * M2M3;
        x += (c2[i] * i2) % MOD2 * M1M3;
        x += (c3[i] * i3) % MOD3 * M1M2;
        // B = 2^63, -B <= x, r(real value) < B
        // (x, x - M, x - 2M, or x - 3M) = r (mod 2B)
        // r = c1[i] (mod MOD1)
        // focus on MOD1
        // r = x, x - M', x - 2M', x - 3M' (M' = M % 2^64) (mod 2B)
        // r = x,
        //     x - M' + (0 or 2B),
        //     x - 2M' + (0, 2B or 4B),
        //     x - 3M' + (0, 2B, 4B or 6B) (without mod!)
        // (r - x) = 0, (0)
        //           - M' + (0 or 2B), (1)
        //           -2M' + (0 or 2B or 4B), (2)
        //           -3M' + (0 or 2B or 4B or 6B) (3) (mod MOD1)
        // we checked that
        //   ((1) mod MOD1) mod 5 = 2
        //   ((2) mod MOD1) mod 5 = 3
        //   ((3) mod MOD1) mod 5 = 4
        long long diff =
            c1[i] - internal::safe_mod((long long)(x), (long long)(MOD1));
        if (diff < 0) diff += MOD1;
        static constexpr unsigned long long offset[5] = {
            0, 0, M1M2M3, 2 * M1M2M3, 3 * M1M2M3};
        x -= offset[diff % 5];
        c[i] = x;
    }

    return c;
}

}  // namespace atcoder

using namespace atcoder;

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    
    ll N,M,K,L,y=0,x=0,an=0;
    cin>>N>>M>>K>>L;
    vector<ll> U(M*M,0),V(M*M,0);
    string S;
    for(int i=0;i<N;i++){
        cin>>S; 
        for(int j=0;j<N;j++)U[i*M+j]=(S[j]=='X');
    }
    cin>>S;
    for(auto s:S){
        if(s=='U')y--;
        else if(s=='D')y++;
        else if(s=='R')x++;
        else x--;
        V[y*M+x]++;
    }
    auto W=convolution_ll(U,V);
    for(int i=0;i<M*M;i++)if(W[i]>=K)an++;
    cout<<an<<endl;
}
accuracy: 1
time_ms: 100
memory_kb: 24940
final_rank: 8

code_snippet: #include <bits/stdc++.h>

using namespace std;
#define rep(i, x) for(int i = 0; i < (x); i++)
using ll = long long;
#define all(v) v.begin(), v.end()

struct Dinic {
	struct Edge {
		int to, rev;
		ll c, oc;
		ll flow() { return max(oc - c, 0ll); }
	};
	vector<int> lvl, ptr, q;
	vector<vector<Edge>> adj;
	Dinic(int n) : lvl(n), ptr(n), q(n), adj(n) {}
	void add_edge(int a, int b, ll c, ll rcap = 0) {
		adj[a].push_back({b, (int)adj[b].size(), c, c});
		adj[b].push_back({a, (int)adj[a].size() - 1, rcap, rcap});
	}
	ll dfs(int v, int t, ll f) {
		if(v == t or !f) return f;
		for(int &i = ptr[v]; i < (int)adj[v].size(); i++) {
			Edge &e = adj[v][i];
			if(lvl[e.to] == lvl[v] + 1) {
				if(ll p = dfs(e.to, t, min(f, e.c))) {
					e.c -= p, adj[e.to][e.rev].c += p;
					return p;
				}
			}
		}
		return 0;
	}
	ll calc(int s, int t) {
		ll flow = 0;
		q[0] = s;
		rep(L, 31) do {
			lvl = ptr = vector<int>(q.size());
			int qi = 0, qe = lvl[s] = 1;
			while(qi < qe and !lvl[t]) {
				int v = q[qi++];
				for(Edge e : adj[v]) {
					if(!lvl[e.to] and e.c >> (30 - L)) {
						q[qe++] = e.to, lvl[e.to] = lvl[v] + 1;
					}
				}
			}
			while(ll p = dfs(s, t, LLONG_MAX)) flow += p;
		}
		while(lvl[t])
			;
		return flow;
	}
};

struct uf {
	vector<int> par;
	uf(int n) : par(n, -1) {}
	int root(int x) {
		if(par[x] < 0) return x;
		return par[x] = root(par[x]);
	}
	bool same(int x, int y) { return root(x) == root(y); }
	bool unite(int x, int y) {
		x = root(x), y = root(y);
		if(x == y) return false;
		if(par[x] > par[y]) swap(x, y);
		par[x] += par[y];
		par[y] = x;
		return true;
	}
	int size(int x) { return -par[root(x)]; }
};

typedef complex<double> C;
typedef vector<double> vd;

void fft(vector<C> &a) {
	int n = a.size(), L = 31 - __builtin_clz(n);
	static vector<complex<long double>> R(2, 1);
	static vector<C> rt(2, 1);
	for(static int k = 2; k < n; k *= 2) {
		R.resize(n);
		rt.resize(n);
		auto x = polar(1.0L, acos(-1.0L) / k);
		for(int i = k; i < 2 * k; i++) rt[i] = R[i] = i & 1 ? R[i / 2] * x : R[i / 2];
	}
	vector<int> rev(n);
	rep(i, n) rev[i] = (rev[i / 2] | (i & 1) << L) / 2;
	rep(i, n) if(i < rev[i]) swap(a[i], a[rev[i]]);
	for(int k = 1; k < n; k *= 2) {
		for(int i = 0; i < n; i += 2 * k) {
			rep(j, k) {
				auto x = (double *)&rt[j + k], y = (double *)&a[i + j + k];
				C z(x[0] * y[0] - x[1] * y[1], x[0] * y[1] + x[1] * y[0]);
				a[i + j + k] = a[i + j] - z;
				a[i + j] += z;
			}
		}
	}
}

vector<double> conv(vector<double> a, vector<double> b) {
	vector<double> res(a.size() + b.size() - 1);
	int L = 32 - __builtin_clz(res.size()), n = 1 << L;
	vector<C> in(n), out(n);
	copy(all(a), begin(in));
	rep(i, b.size()) in[i].imag(b[i]);
	fft(in);
	for(C &x : in) x *= x;
	rep(i, n) out[i] = in[-i & (n - 1)] - conj(in[i]);
	fft(out);
	rep(i, res.size()) res[i] = imag(out[i]) / (4 * n);
	return res;
}

int main() {
	int n, m, k, l;
	cin >> n >> m >> k >> l;
	vector<double> B(m * m);
	rep(i, n) {
		string s;
		cin >> s;
		rep(j, n) {
			B[i * m + j] = (s[j] == 'X');
		}
	}
	string s;
	cin >> s;
	vector<double> C(m * m);
	int x = 0, y = 0;
	for(auto c : s) {
		if(c == 'D') x++;
		if(c == 'R') y++;
		if(c == 'U') x--;
		if(c == 'L') y--;
		C[x * m + y]++;
	}
	auto res = conv(B, C);
	int ans = 0;
	for(auto v : res) {
		if(round(v) >= k) ans++;
	}
	cout << ans << endl;
}
accuracy: 1
time_ms: 50
memory_kb: 58508
final_rank: 12

code_snippet: #include <bits/stdc++.h>

using namespace std;
#define rep(i, x) for(int i = 0; i < (x); i++)
using ll = long long;
#define all(v) v.begin(), v.end()

struct Dinic {
	struct Edge {
		int to, rev;
		ll c, oc;
		ll flow() { return max(oc - c, 0ll); }
	};
	vector<int> lvl, ptr, q;
	vector<vector<Edge>> adj;
	Dinic(int n) : lvl(n), ptr(n), q(n), adj(n) {}
	void add_edge(int a, int b, ll c, ll rcap = 0) {
		adj[a].push_back({b, (int)adj[b].size(), c, c});
		adj[b].push_back({a, (int)adj[a].size() - 1, rcap, rcap});
	}
	ll dfs(int v, int t, ll f) {
		if(v == t or !f) return f;
		for(int &i = ptr[v]; i < (int)adj[v].size(); i++) {
			Edge &e = adj[v][i];
			if(lvl[e.to] == lvl[v] + 1) {
				if(ll p = dfs(e.to, t, min(f, e.c))) {
					e.c -= p, adj[e.to][e.rev].c += p;
					return p;
				}
			}
		}
		return 0;
	}
	ll calc(int s, int t) {
		ll flow = 0;
		q[0] = s;
		rep(L, 31) do {
			lvl = ptr = vector<int>(q.size());
			int qi = 0, qe = lvl[s] = 1;
			while(qi < qe and !lvl[t]) {
				int v = q[qi++];
				for(Edge e : adj[v]) {
					if(!lvl[e.to] and e.c >> (30 - L)) {
						q[qe++] = e.to, lvl[e.to] = lvl[v] + 1;
					}
				}
			}
			while(ll p = dfs(s, t, LLONG_MAX)) flow += p;
		}
		while(lvl[t])
			;
		return flow;
	}
};

struct uf {
	vector<int> par;
	uf(int n) : par(n, -1) {}
	int root(int x) {
		if(par[x] < 0) return x;
		return par[x] = root(par[x]);
	}
	bool same(int x, int y) { return root(x) == root(y); }
	bool unite(int x, int y) {
		x = root(x), y = root(y);
		if(x == y) return false;
		if(par[x] > par[y]) swap(x, y);
		par[x] += par[y];
		par[y] = x;
		return true;
	}
	int size(int x) { return -par[root(x)]; }
};

typedef complex<double> C;
typedef vector<double> vd;

void fft(vector<C> &a) {
	int n = a.size(), L = 31 - __builtin_clz(n);
	static vector<complex<long double>> R(2, 1);
	static vector<C> rt(2, 1);
	for(static int k = 2; k < n; k *= 2) {
		R.resize(n);
		rt.resize(n);
		auto x = polar(1.0L, acos(-1.0L) / k);
		for(int i = k; i < 2 * k; i++) rt[i] = R[i] = i & 1 ? R[i / 2] * x : R[i / 2];
	}
	vector<int> rev(n);
	rep(i, n) rev[i] = (rev[i / 2] | (i & 1) << L) / 2;
	rep(i, n) if(i < rev[i]) swap(a[i], a[rev[i]]);
	for(int k = 1; k < n; k *= 2) {
		for(int i = 0; i < n; i += 2 * k) {
			rep(j, k) {
				auto x = (double *)&rt[j + k], y = (double *)&a[i + j + k];
				C z(x[0] * y[0] - x[1] * y[1], x[0] * y[1] + x[1] * y[0]);
				a[i + j + k] = a[i + j] - z;
				a[i + j] += z;
			}
		}
	}
}

vector<double> conv(vector<double> a, vector<double> b) {
	vector<double> res(a.size() + b.size() - 1);
	int L = 32 - __builtin_clz(res.size()), n = 1 << L;
	vector<C> in(n), out(n);
	copy(all(a), begin(in));
	rep(i, b.size()) in[i].imag(b[i]);
	fft(in);
	for(C &x : in) x *= x;
	rep(i, n) out[i] = in[-i & (n - 1)] - conj(in[i]);
	fft(out);
	rep(i, res.size()) res[i] = imag(out[i]) / (4 * n);
	return res;
}

int main() {
	int n, m, k, l;
	cin >> n >> m >> k >> l;
	vector<double> B(m * m);
	rep(i, n) {
		string s;
		cin >> s;
		rep(j, n) {
			B[i * m + j] = (s[j] == 'X');
		}
	}
	string s;
	cin >> s;
	vector<double> C(m * m);
	int x = 0, y = 0;
	for(auto c : s) {
		if(c == 'D') x++;
		if(c == 'R') y++;
		if(c == 'U') x--;
		if(c == 'L') y--;
		C[x * m + y]++;
	}
	auto res = conv(B, C);
	int ans = 0;
	for(auto v : res) {
		if(v + 1e-8 >= k) ans++;
	}
	cout << ans << endl;
}
accuracy: 0.9310344827586207
time_ms: 50
memory_kb: 58532
final_rank: 18

code_snippet: #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2977"
#include <bits/stdc++.h>
using namespace std;

vector<complex<double>> encode(vector<long long> &a){
    int N = a.size();
    vector<complex<double>> ret(N);
    for(int i = 0;i < N;i++){
        ret[i] = complex<double>(a[i],0);
    }
    return ret;
}
 
//複素数配列を整数へ
vector<long long> decode(vector<complex<double>> &a){
    int N = a.size();
    vector<long long> ret(N);
    for(int i = 0;i < N;i++){
        ret[i] = (long long)round(a[i].real());
    }
    return ret;
}
 
//非再帰
void FFT(vector<complex<double>> &a,int reverse = false) {
    int n = a.size();
    int h = 0; 
    for (int i = 0; 1 << i < n; i++) h++;
    for (int i = 0; i < n; i++) {
        int j = 0;
        for (int k = 0; k < h; k++) j |= (i >> k & 1) << (h - 1 - k);
        if (i < j) swap(a[i], a[j]);
    }
    for (int b = 1; b < n; b *= 2) {
        for (int j = 0; j < b; j++) {
            double p2 = 2*acos(-1);
            if(reverse)p2 *= -1;
            complex<double> w = exp(complex<double>(0,p2*j/(double)(2*b)));
            for (int k = 0; k < n; k += b * 2) {
                complex<double> s = a[j+k];         
                complex<double> t = a[j+k+b]*w; 
                a[j+k] = s+t;                    
                a[j+k+b] = s-t;                 
            }
        }
    }
    if (reverse)for (int i = 0; i < n; i++) a[i] /= (double)n;
    return;
}
 
vector<long long> convolution(vector<long long> &a,vector<long long> &b){
    vector<complex<double>> A = encode(a),B = encode(b);
    int s = (int)a.size()+(int)b.size()-1;
    int t = 1;
    while(t < s)t *= 2;
    A.resize(t);B.resize(t);
    FFT(A,0);FFT(B,0);
    for(int i = 0;i < t;i++){
        A[i] *= B[i];
    }
    FFT(A,1);
    A.resize(s);
    return decode(A);
}

int main() {
    int N, M, K, L;
    cin >> N >> M >> K >> L;
    vector<string> bomb(N);
    string s;
    for(int i=0;i<N;i++){
        cin >> bomb[i];
    }
    cin >> s;
    vector<long long> a((M-N+1)*M), b(N*M);
    for(int i=0;i<N;i++){
        for(int j=0;j<N;j++){
            if(bomb[i][j] == 'X'){
                b[i*M+j] = 1;
            }
        }
    }
    int x=0, y=0;
    for(int i=0;i<L;i++){
        if(s[i] == 'U') y--;
        if(s[i] == 'D') y++;
        if(s[i] == 'L') x--;
        if(s[i] == 'R') x++;
        a[y*M+x]++;
    }
    auto c = convolution(a,b);
    int cnt = 0;
    for(int i=0;i<M;i++){
        for(int j=0;j<M;j++){
            if(c[i*M+j] >= K){
                cnt++;
            }
        }
    }
    cout << cnt << endl;
    return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 18632
final_rank: 4

code_snippet: #include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
#include <set>
#include <iomanip>
#include <queue>
#include <string>
#include <map>
#include <fstream>
#include <cassert>
#include <stack>
#include <climits>
#include <array>
#include <unordered_set>
#include <unordered_map>
#include <memory>
#include <functional>
#include <cfloat>
#include <numeric>
#include <random>
#include <sstream>
#include <bitset>
#include <complex>
int log2ceil(int n) {
	int result{ 0 };
	while (n > 1) {
		++result;
		n = (n + 1) >> 1;
	}
	return result;
}

using Vec = std::vector<std::complex<double>>;

Vec operator*(const Vec& vec, const std::complex<double> value) {
	auto result = vec;
	for (auto& v : result) v *= value;
	return result;
}
Vec operator/(const Vec& vec, const std::complex<double> value) {
	auto result = vec;
	for (auto& v : result) v /= value;
	return result;
}
Vec& operator/=(Vec& vec, const std::complex<double> other) {
	for (auto i = 0; i < vec.size(); ++i) {
		vec[i] /= other;
	}
	return vec;
}
Vec operator+(const Vec& vec, const Vec& right) {
	auto result = vec;
	for (auto i = 0; i < result.size(); ++i) {
		result[i] += right[i];
	}
	return result;
}
Vec operator-(const Vec& vec, const Vec& right) {
	auto result = vec;
	for (auto i = 0; i < result.size(); ++i) {
		result[i] -= right[i];
	}
	return result;
}
Vec& operator+=(Vec& vec, const Vec& other) {
	for (auto i = 0; i < vec.size(); ++i) {
		vec[i] += other[i];
	}
	return vec;
}

template<typename F>
std::vector<F> fft(const std::vector<F>& vec, const bool inverse = false) {
	const auto PI = std::acos(-1);
	const auto log2 = log2ceil(vec.size());
	auto result = vec;
	result.resize(1 << log2);
	for (auto i = 0; i < result.size(); ++i) {
		int j = 0;
		for (auto d = 0; d < log2; ++d) {
			j <<= 1;
			j += (i >> d) & 1;
		}
		if (i < j) std::swap(result[i], result[j]);
	}
	for (auto b = 0; b < log2; ++b) {
		const auto width = 1 << b;
		for (auto r = 0; r < width; ++r) {
			const auto w = std::complex<double>(std::cos(r * PI  / width), std::sin(r * PI * (inverse ? 1 : -1) / width));
			for (auto i = r; i < result.size(); i += width << 1) {
				const auto t = result[i + width] * w;
				result[i + width] = result[i] - t;
				result[i] += t;
			}
		}
	}
	if (inverse) {
		for (auto& v : result) v /= result.size();
	}
	return result;
}

Vec to_vec(const std::vector<int>& a) {
	Vec result(a.size());
	for (auto i = 0; i < result.size(); ++i) {
		result[i] = std::complex<double>(a[i], 0);
	}
	return result;
}
std::vector<Vec> to_vec(const std::vector<std::vector<int>>& a) {
	std::vector<Vec> result(a.size());
	for (auto i = 0; i < a.size(); ++i) {
		result[i] = to_vec(a[i]);
	}
	return result;
}
void resize(std::vector<Vec>& a, const int height, const int width) {
	a.resize(height);
	for (auto& v : a) v.resize(width);
}

std::vector<std::vector<double>> fold_fft(const std::vector<std::vector<int>> a, const std::vector<std::vector<int>> b) {
	const auto height = a.size() + b.size() - 1;
	const auto width = a[0].size() + b[0].size() - 1;
	auto vec_a = to_vec(a); resize(vec_a, 1 << log2ceil(height), 1 << log2ceil(width));
	auto vec_b = to_vec(b); resize(vec_b, 1 << log2ceil(height), 1 << log2ceil(width));
	for (auto& v : vec_a) v = fft(v);
	vec_a = fft(vec_a);
	for (auto& v : vec_b) v = fft(v);
	vec_b = fft(vec_b);
	auto vec_c = vec_a;
	for (auto i = 0; i < vec_c.size(); ++i) {
		for (auto j = 0; j < vec_c[i].size(); ++j) {
			vec_c[i][j] *= vec_b[i][j];
		}
	}
	for (auto& v : vec_c) v = fft(v, true);
	vec_c = fft(vec_c, true);
	std::vector<std::vector<double>> result(height, std::vector<double>(width));
	for (auto i = 0; i < result.size(); ++i) {
		for (auto j = 0; j < result[i].size(); ++j) {
			result[i][j] = vec_c[i][j].real();
		}
	}
	return result;
}

std::vector<std::vector<int>> bomber_pattern(const std::string order) {
	std::vector<std::pair<int, int>> coordinates; coordinates.emplace_back(0, 0);
	for (const auto c : order) {
		const auto [x, y] = coordinates.back();
		switch (c) {
		case 'U': coordinates.emplace_back(x, y - 1); break;
		case 'D': coordinates.emplace_back(x, y + 1); break;
		case 'R': coordinates.emplace_back(x + 1, y); break;
		case 'L': coordinates.emplace_back(x - 1, y); break;
		default: throw 0;
		}
	}
	const auto max_x = std::max_element(coordinates.begin(), coordinates.end(), [](const std::pair<int, int>& a, const std::pair<int, int>& b) {return a.first < b.first; })->first;
	const auto max_y = std::max_element(coordinates.begin(), coordinates.end(), [](const std::pair<int, int>& a, const std::pair<int, int>& b) {return a.second < b.second; })->second;
	std::vector<std::vector<int>> result(max_y + 1, std::vector<int>(max_x + 1, 0));
	for (const auto [x, y] : coordinates) {
		++result[y][x];
	}
	--result[0][0];
	return result;
}

int main() {
	int pattern_size, field_size, min_count, length;
	std::cin >> pattern_size >> field_size >> min_count >> length;
	std::vector<std::vector<int>> pattern(pattern_size);
	for (auto& p : pattern) {
		std::string pat; std::cin >> pat;
		for (const auto c : pat) {
			p.push_back(c == 'X' ? 1 : 0);
		}
	}
	std::string order; std::cin >> order;
	const auto bomber = bomber_pattern(order);
	const auto count = fold_fft(pattern, bomber);
	int result{ 0 };
	for (const auto& line : count) {
		for (const auto c : line) {
			if (c + 1e-6 >= min_count) {
				++result;
			}
		}
	}
	std::cout << result << '\n';
}
accuracy: 1
time_ms: 60
memory_kb: 22184
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
using ll = long long;

template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b)a=b;};
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b)a=b;};

template<typename T> void drop(T x){cout<<x<<endl;exit(0);};

template<typename T, T MOD = 1000000007>
struct Mint{
  static constexpr T mod = MOD;
  T v;
  Mint():v(0){}
  Mint(signed v):v(v){}
  Mint(long long t){v=t%MOD; if(v<0) v += MOD;}

  Mint pow(long long k){
    Mint res(1), tmp(v);
    while(k){
      if(k&1)  res *= tmp;
      tmp *= tmp;
      k>>=1;
    }
    return res;
  }

  static Mint add_identity(){return Mint(0);}
  static Mint mul_identity(){return Mint(1);}

  Mint inv(){return pow(MOD- 2);}

  Mint& operator+=(Mint a){v += a.v; if(v>=MOD) v -= MOD; return *this;}
  Mint& operator-=(Mint a){v += MOD - a.v; if(v>=MOD) v-=MOD; return *this;}
  Mint& operator*=(Mint a){v = 1LL * v * a.v%MOD; return *this;}
  Mint& operator/=(Mint a){return (*this) *= a.inv();}

  Mint operator+(Mint a)const{return Mint(v)+=a;}
  Mint operator-(Mint a)const{return Mint(v)-=a;}
  Mint operator*(Mint a)const{return Mint(v)*=a;}
  Mint operator/(Mint a)const{return Mint(v)/=a;}

  Mint operator-()const{return v?Mint(MOD-v):Mint(v);}

  bool operator==(const Mint a)const{return v == a.v;}
  bool operator!=(const Mint a)const{return v != a.v;}
  bool operator <(const Mint a)const{return v < a.v;}
};

template<typename T, T MOD> constexpr T Mint<T, MOD>:: mod;
template<typename T, T MOD>
ostream& operator<<(ostream &os, Mint<T, MOD> m){os<<m.v;return os;}

constexpr int bmds(int x){
  const int v[] = {1012924417};
  return v[x];
}

constexpr int brts(int x){
  const int v[] = {5, 5, 3, 3, 3};
  return v[x];
}

template<int X>
struct NTT{
  static constexpr int md = bmds(X);
  static constexpr int rt = brts(X);
  using M = Mint<int, md>;
  vector<vector<M> > rts, rrts;

  void ensure_base(int n){
    if((int)rts.size() >= n) return;
    rts.resize(n); rrts.resize(n);
    for(int i=1;i<n;i<<=1){
      if(!rts[i].empty()) continue;
      M w=M(rt).pow((md - 1)/(i<<1));
      M rw = w.inv();

      rts[i].resize(i); rrts[i].resize(i);
      rts[i][0]=M(1); rrts[i][0] = M(1);
      for(int k=1;k<i;k++){
        rts[i][k] = rts[i][k-1] * w;
        rrts[i][k] = rrts[i][k-1] * rw;
      }
    }
  }

  void ntt(vector<M> &as, bool f, int n = -1){
    if(n == -1) n = as.size();
    assert((n & (n - 1)) == 0);
    ensure_base(n);

    for(int i=0, j=1;j+1<n;j++){
      for(int k=n>>1;k>(i^=k); k>>=1);
      if(i > j) swap(as[i], as[j]);
    }

    for(int i=1;i<n;i<<=1){
      for(int j=0;j<n;j+=i*2){
        for(int k=0;k<i;k++){
          M z = as[i+j+k] * (f? rrts[i][k] : rts[i][k]);
          as[i+j+k] = as[j+k] -z;
          as[j+k] += z;
        }
      }
    }

    if(f){
      M tmp = M(n).inv();
      for(int i=0;i<n;i++) as[i] *= tmp;
    }
  }

  vector<M> multiply(vector<M> as, vector<M> bs){
    int need = as.size() + bs.size() - 1;
    int sz = 1;
    while(sz < need) sz <<= 1;
    as.resize(sz, M(0));
    bs.resize(sz, M(0));

    ntt(as, 0); ntt(bs, 0);
    for(int i=0;i<sz;i++) as[i] *= bs[i];
    ntt(as, 1);
    as.resize(need);
    return as;
  }
};

template<int X> constexpr int NTT<X>:: md;
template<int X> constexpr int NTT<X>:: rt;

template<typename T, typename Transformer>
struct Convolution2D{
  using Matrix = vector< vector<T> > ;
  const Transformer tran;
  Convolution2D(Transformer tran): tran(tran){}

  void transpose(Matrix &as){
    int n = as.size(), m = as[0].size();
    Matrix cs(as);
    as.assign(m, vector<T>(n));

    for(int i=0;i<n;i++){
      for(int j=0;j<m;j++)
        as[j][i] = cs[i][j];
    }
  }

  void transform(Matrix &as, bool f){
    for(int t=0;t<2;t++){
      for(auto &a:as) tran(a, f);
      transpose(as);
    }
  }

  Matrix multiply(Matrix as, Matrix bs){
    int nt = as.size() + bs.size() - 1;
    int mt = as[0].size() + bs[0].size() - 1;
    int n = 1, m = 1;
    while(n < nt) n <<= 1;
    while(m < mt) m <<= 1;
    as.resize(n), bs.resize(n);
    for(int i=0;i<n;i++){
      as[i].resize(m ,T(0));
      bs[i].resize(m ,T(0));
    }
    //cout<<n<<" "<<m<<endl;
    transform(as, 0); transform(bs, 0);
    for(int i=0;i<n;i++)
      for(int j=0;j<m;j++) as[i][j] *= bs[i][j];

    transform(as, 1);
    return as;
  }
};

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

  int n,m,k,l;
  cin>>n>>m>>k>>l;
  vector<string> bs(n);
  for(int i=0;i<n;i++) cin>>bs[i];

  string s;
  cin>>s;

  NTT<0> ntt;
  using M = NTT<0>::M;
  auto tran=[&](auto &as,bool f){ntt.ntt(as,f);};
  Convolution2D<M, decltype(tran)> conv(tran);

  using Matrix=Convolution2D<M, decltype(tran)>::Matrix;

  const int DEBUG = 0;

  Matrix A(n,vector<M>(n,0));
  for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)
      A[i][j]=M(bs[i][j]=='X');

  Matrix B(m-n+1,vector<M>(m-n+1,0));
  int cy=0,cx=0;
  for(int i=0;i<l;i++){
    if(s[i]=='L') cx--;
    if(s[i]=='R') cx++;
    if(s[i]=='U') cy--;
    if(s[i]=='D') cy++;

    B[cy][cx]+=M(1);

    if(DEBUG) cout<<cy<<" "<<cx<<endl;
  }

  auto C=conv.multiply(A,B);

  if(DEBUG){
    cout<<endl;
    for(int i=0;i<n;i++){
      for(int j=0;j<n;j++)
        cout<<A[i][j].v<<" ";
      cout<<endl;
    }
    cout<<endl;
    for(int i=0;i<m-n+1;i++){
      for(int j=0;j<m-n+1;j++)
        cout<<B[i][j].v<<" ";
      cout<<endl;
    }
    cout<<endl;
    for(int i=0;i<m;i++){
      for(int j=0;j<m;j++)
        cout<<C[i][j].v<<" ";
      cout<<endl;
    }
    cout<<endl;
  }

  int ans=0;
  for(int i=0;i<m;i++)
    for(int j=0;j<m;j++)
      if(C[i][j].v>=k) ans++;

  cout<<ans<<endl;
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 8652
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef double LD;
const int maxn = 505;
int n, m, k, l;
char g[maxn][maxn];
string s;
const LD PI = 3.14159265358979;
struct C {
    LD r, i;
    C(LD r = 0, LD i = 0)
        : r(r)
        , i(i)
    {
    }
    C operator+(const C& a) const { return C(r + a.r, i + a.i); }
    C operator-(const C& a) const { return C(r - a.r, i - a.i); }
    C operator*(const C& a) const
    {
        return C(r * a.r - i * a.i, r * a.i + i * a.r);
    }
} a[maxn * maxn * 4], b[maxn * maxn * 4];
void FFT(C x[], int n, int p)
{
    for (int i = 0, t = 0; i < n; ++i) {
        if (i > t) swap(x[i], x[t]);
        for (int j = n >> 1; (t ^= j) < j; j >>= 1)
            ;
    }
    for (int h = 2; h <= n; h <<= 1) {
        C wn(cos(p * 2 * PI / h), sin(p * 2 * PI / h));
        for (int i = 0; i < n; i += h) {
            C w(1, 0), u;
            for (int j = i, k = h >> 1; j < i + k; ++j) {
                u = x[j + k] * w;
                x[j + k] = x[j] - u;
                x[j] = x[j] + u;
                w = w * wn;
            }
        }
    }
    if (p == -1)
        for (int i = 0; i < n; ++i) x[i].r /= n;
}
void conv(C a[], C b[], int n)
{
    FFT(a, n, 1);
    FFT(b, n, 1);
    for (int i = 0; i < n; ++i) a[i] = a[i] * b[i];
    FFT(a, n, -1);
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> m >> k >> l;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++) cin >> g[i][j];
    cin >> s;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (g[i][j] == 'X') { a[i * m + j].r = 1.0; }
        }
    }
    int x = 0, y = 0;
    for (int i = 0; i < s.length(); i++) {
        if (s[i] == 'D') x++;
        if (s[i] == 'U') x--;
        if (s[i] == 'R') y++;
        if (s[i] == 'L') y--;
        b[x * m + y].r = b[x * m + y].r + 1.0;
    }
    int tmp = 1;
    while (tmp <= m * m * 2) tmp <<= 1;
    conv(a, b, tmp);
    int ans = 0;
    for (int i = 0; i < m * m * 2 + 1; i++) {
        if (int(a[i].r + 0.5) >= k) ans++;
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 80
memory_kb: 35888
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;


typedef double LD;
const LD PI = 3.14159265358979;
struct C
{
    LD r, i;
    C(LD r = 0, LD i = 0) : r(r), i(i) {}
    C operator+(const C &a) const
    {
        return C(r + a.r, i + a.i);
    }
    C operator-(const C &a) const
    {
        return C(r - a.r, i - a.i);
    }
    C operator*(const C &a) const
    {
        return C(r * a.r - i * a.i, r * a.i + i * a.r);
    }
};
void FFT(C x[], int n, int p)
{
    for (int i = 0, t = 0; i < n; ++i)
    {
        if (i > t)
            swap(x[i], x[t]);
        for (int j = n >> 1; (t ^= j) < j; j >>= 1)
            ;
    }
    for (int h = 2; h <= n; h <<= 1)
    {
        C wn(cos(p * 2 * PI / h), sin(p * 2 * PI / h));
        for (int i = 0; i < n; i += h)
        {
            C w(1, 0), u;
            for (int j = i, k = h >> 1; j < i + k; ++j)
            {
                u = x[j + k] * w;
                x[j + k] = x[j] - u;
                x[j] = x[j] + u;
                w = w * wn;
            }
        }
    }
    if (p == -1)
        for (int i = 0; i < n; ++i)
            x[i].r /= n;
}
void conv(C a[], C b[], int n)
{
    FFT(a, n, 1);
    FFT(b, n, 1);
    for (int i = 0; i < n; ++i)
        a[i] = a[i] * b[i];
    FFT(a, n, -1);
}

char mp[505][505];
C a[251000], b[251000];
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int n,m,k,len,ans=0;
	cin>>n>>m>>k>>len;
	for(int i=0;i<n;++i)
	{
		for(int j=0;j<n;++j)
		{
			cin>>mp[i][j];
			a[i*m+j].r=((mp[i][j]=='X')?1:0);
		}
	}
	int nowx=0,nowy=0;
	for(int i=0;i<len;++i)
	{
		char c; cin>>c;
		if(c=='R') ++nowy;
		if(c=='D') ++nowx;
		if(c=='L') --nowy;
		if(c=='U') --nowx;
		b[nowx*m+nowy].r++;
	}
	int L=1;
	while(L<=m*m) L<<=1;
	conv(a,b,L*2);
	for(int i=0;i<m;++i)
	{
		for(int j=0;j<m;++j)
		{
			if((int)(a[i*m+j].r+0.5)>=k) ans++;
		}
	}
	cout<<ans<<endl;
	return 0;
}
accuracy: 0.3793103448275862
time_ms: 30
memory_kb: 11412
final_rank: 19

code_snippet: /*
 * @Author: zhouxiaolun
 * @Date: 2020-10-06 21:12:57
 * @LastEditTime: 2020-10-06 22:07:50
 */
#include <bits/stdc++.h>
using namespace std;
//define ONLINE_JUDGE
#ifndef ONLINE_JUDGE
#    define debug(x) cout << #    x << '\t' << x << endl
#else
#    define debug(x)
#endif
typedef long long ll;
typedef unsigned long long ull;
const ll mod = 1e9 + 7;
const double eps = 1e-8;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
#define fast                     \
    ios::sync_with_stdio(false); \
    cin.tie(0);                  \
    cout.tie(0)
typedef pair<int, int> pii;
const int INF = 0x3f3f3f3f;
#define lowbit(x) ((x) & -(x))
#define mem(a, b) memset(a, b, sizeof(a))
#define endl '\n'
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
//#define int long long
//ll gcd(ll a, ll b){a = abs(a);b = abs(b);return a == 0 ? b : gcd(b % a, a);}
//inline ll Pow(ll a, ll n, ll MOD) { ll t = 1; a %= MOD; while (n > 0) { if (n & 1) t = t * a % MOD; a = a * a % MOD, n >>= 1; } return t % MOD; }
const double PI = acos(-1.0);
struct Complex
{
    double x, y;
    Complex(double _x = 0.0, double _y = 0.0)
    {
        x = _x;
        y = _y;
    }
    Complex operator-(const Complex& b) const
    {
        return Complex(x - b.x, y - b.y);
    }
    Complex operator+(const Complex& b) const
    {
        return Complex(x + b.x, y + b.y);
    }
    Complex operator*(const Complex& b) const
    {
        return Complex(x * b.x - y * b.y, x * b.y + y * b.x);
    }
};
/*
 * 进行 FFT 和 IFFT 前的反置变换
 * 位置 i 和 i 的二进制反转后的位置互换
 *len 必须为 2 的幂
 */
void change(Complex y[], int len)
{
    int i, j, k;
    for (int i = 1, j = len / 2; i < len - 1; i++) {
        if (i < j) swap(y[i], y[j]);
        // 交换互为小标反转的元素，i<j 保证交换一次
        // i 做正常的 + 1，j 做反转类型的 + 1，始终保持 i 和 j 是反转的
        k = len / 2;
        while (j >= k) {
            j = j - k;
            k = k / 2;
        }
        if (j < k) j += k;
    }
}
/*
 * 做 FFT
 *len 必须是 2^k 形式
 *on == 1 时是 DFT，on == -1 时是 IDFT
 */
void fft(Complex y[], int len, int on)
{
    change(y, len);
    for (int h = 2; h <= len; h <<= 1) {
        Complex wn(cos(2 * PI / h), sin(on * 2 * PI / h));
        for (int j = 0; j < len; j += h) {
            Complex w(1, 0);
            for (int k = j; k < j + h / 2; k++) {
                Complex u = y[k];
                Complex t = w * y[k + h / 2];
                y[k] = u + t;
                y[k + h / 2] = u - t;
                w = w * wn;
            }
        }
    }
    if (on == -1) {
        for (int i = 0; i < len; i++) {
            y[i].x /= len;
        }
    }
}

const int maxn = 1000;
int a[maxn * maxn*2], b[maxn * maxn*2];
Complex x1[maxn * maxn*2], x2[maxn * maxn*2];

signed main()
{
    fast;
    int n, m, k, l;
    cin >> n >> m >> k >> l;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            char ch;
            cin >> ch;
            if (ch == 'X') {
                a[i * m + j]++;
            }
        }
    }
    int x = 0;
    int y = 0;
    for (int i = 0; i < l; i++) {
        char ch;
        cin >> ch;
        if (ch == 'U') {
            x--;
        }
        else if (ch == 'D') {
            x++;
        }
        else if (ch == 'L') {
            y--;
        }
        else {
            y++;
        }
        b[x * m + y]++;
    }
    int len1 = m * m;
    int len2 = m * m;
    // for (int i = 0; i < m*m; i++) {
    //     cout<<a[i]<<" ";
    // }
    // cout<<endl;
    // for (int i = 0; i < m*m; i++) {
    //     cout<<b[i]<<" ";
    // }
    // cout<<endl;
    int len = 1;
    while (len < len1 * 2 || len < len2 * 2) len <<= 1;
    for (int i = 0; i < len1; i++) x1[i] = Complex(a[len1 - 1 - i], 0);
    for (int i = len1; i < len; i++) x1[i] = Complex(0, 0);
    for (int i = 0; i < len2; i++) x2[i] = Complex(b[len2 - 1 - i], 0);
    for (int i = len2; i < len; i++) x2[i] = Complex(0, 0);
    fft(x1, len, 1);
    fft(x2, len, 1);
    for (int i = 0; i < len; i++) x1[i] = x1[i] * x2[i];
    fft(x1, len, -1);
    for (int i = 0; i < len; i++) a[i] = int(x1[i].x + 0.5);
    int ans = 0;
    for (int i = 0; i < len; i++) {
        if(a[i]>=k) ans++;
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 69060
final_rank: 14

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#define rep(i,l,r) for(int i=(l);i<=(r);++i)
#define per(i,r,l) for(int i=(r);i>=(l);--i)
using namespace std;
typedef double db;
const int M=1100,O=2e5+10;
const db PI=acos(-1.0);
int dx[128],dy[128],cnt,x,y,K,n,m,len,N,r[M],l;
char s[O];
struct cp{
    db r,i;
    cp(db a=0,db b=0):r(a),i(b){}
}a[M][M],b[M][M],c[M];
inline cp operator +(cp a,cp b){return cp(a.r+b.r,a.i+b.i);}
inline cp operator -(cp a,cp b){return cp(a.r-b.r,a.i-b.i);}
inline cp operator *(cp a,cp b){return cp(a.r*b.r-a.i*b.i,a.r*b.i+a.i*b.r);}
inline cp operator /(cp a,db b){return cp(a.r/b,a.i/b);}
void DFT(cp *a,int k){
    rep(i,0,N-1){
        r[i]=(i&1)?r[i^1]|(1<<l-1):r[i>>1]>>1;
        if(i<r[i]) swap(a[i],a[r[i]]);
    }
    for(int mid=1;mid<N;mid<<=1){
        cp wn(cos(PI/mid),k*sin(PI/mid));
        for(int R=mid<<1,j=0;j<N;j+=R){
            cp w(1,0),*l=a+j,*r=a+j+mid,x,y;
            for(int k=0;k<mid;++k,++l,++r,w=w*wn)
                x=*l,y=(*r)*w,*l=x+y,*r=x-y;
        }
    }
    if(k==-1) rep(i,0,N-1) a[i]=a[i]/N;
}
void DFT_2(cp a[M][M],int k){
    rep(i,0,N-1) DFT(a[i],k);
    //rep(i,0,N-1){rep(j,0,N-1) printf("%.8lf %.8lf ",a[i][j].r,a[i][j].i);puts("");}
    rep(i,0,N-1){
        rep(j,0,N-1) c[j]=a[j][i];DFT(c,k);
        rep(j,0,N-1) a[j][i]=c[j];
    }
}
void conv(){
    for(N=1,l=0;N<m;N<<=1,l++);
    DFT_2(b,1);
    DFT_2(a,1);
    //rep(i,0,N-1){rep(j,0,N-1) printf("%.8lf %.8lf ",a[i][j].r,a[i][j].i);puts("");}
    
    //rep(i,0,N-1){rep(j,0,N-1) printf("%.8lf %.8lf ",b[i][j].r,b[i][j].i);puts("");}
    rep(i,0,N-1) rep(j,0,N-1) a[i][j]=a[i][j]*b[i][j];
    //rep(i,0,N-1){rep(j,0,N-1) printf("%.8lf %.8lf ",a[i][j].r,a[i][j].i);puts("");}
    DFT_2(a,-1);
}
int main(){
    scanf("%d%d%d%d",&n,&m,&K,&len);
    rep(i,0,n-1){
        scanf("%s",s);
        rep(j,0,n-1) b[i][j].r=s[j]=='X';
    }
    scanf("%s",s+1);
    dx['U']=-1;dx['D']=1;dy['R']=1;dy['L']=-1;
    rep(i,1,len){
        x+=dx[s[i]];y+=dy[s[i]];
        a[x][y].r++;
    }
    conv();
    //rep(i,0,m-1){rep(j,0,m-1) printf("%d ",(int)a[i][j].r);puts("");}
    rep(i,0,m-1) rep(j,0,m-1) if(a[i][j].r+0.5>=K) ++cnt;
    printf("%d\n",cnt);
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 41648
final_rank: 11

code_snippet: //qqzkqqzkqqzkqqzkqqzkqqzkqqzkqqzkqqzkqqzkqqzkqqzkqqzkqqzkqqzkqqzkqqzkqqzkqqzkqqzkqqzkqqzkqqzk
#pragma GCC optimize(3)
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#include <iostream>
#include <cstdio>
#include <map>
#include <cstring>
#include <sstream>
#include <vector>
#include <bits/stdc++.h>
using namespace std;

// #define MP make_pair
// #define int long long
// #define us unsigned
//#define LL long long
const int N = 1000;
const int M = 2e5;
#define re register
// const int mod = 19260817;
// const int inf = 999999999;
// char buf[(int)1e8], *ss = buf;
// inline int init()
// {
//     buf[fread(buf, 1, (int)1e8 - 1, stdin)] = '\n';
//     fclose(stdin);
//     return 0;
// }
// const int __START__ = init();

int a, b, c, d, k[M + 10], sum[N + 10][N + 10], top, ans, p[N + 10][N + 10];
char t[N + 10][N + 10], op;
struct node
{
    int x, y;
} s[N * N + 10];

signed main()
{
    scanf("%d%d%d%d\n", &a, &b, &c, &d);
    for (re int i = 1; i <= a; i++)
        scanf("%s\n", t[i] + 1);
    int x = 1, y = 1;
    for (re int i = 1; i <= d; i++)
    {
        scanf("%c", &op);
        if (op == 'R')
        {
            y++;
            p[x][y]++;
        }
        if (op == 'L')
        {
            y--;
            p[x][y]++;
        }
        if (op == 'U')
        {
            x--;
            p[x][y]++;
        }
        if (op == 'D')
        {
            x++;
            p[x][y]++;
        }
    }
    for (re int k = 1; k <= b; k++)
        for (re int l = 1; l <= b; l++)
        {
            if (!p[k][l])
                continue;
            for (re int i = 1; k + i - 1 <= b; i++)
                for (re int j = 1; l + j - 1 <= b; j++)
                {
                    if (t[i][j] == 'X')
                        sum[k + i - 1][l + j - 1] += p[k][l];
                }
        }
    for (re int i = 1; i <= b; i++)
        for (re int j = 1; j <= b; j++)
            if (sum[i][j] >= c)
                ans++;
    printf("%d\n", ans);
    return 0;
}
accuracy: 1
time_ms: 1860
memory_kb: 7052
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;

const double pi = acos(-1.0);

using data_type = complex<double>;
using matrix = vector<vector<data_type>>;

vector<data_type> fft(vector<data_type> v, bool inv = false) {
    const int n = v.size();
    double theta = 2 * pi / n * (inv ? -1 : 1);
    for(int m = n; m >= 2; m >>= 1) {
        int mh = m >> 1;
        data_type theta_i(0, theta);
        for(int i = 0; i < mh; ++i) {
            auto w = exp((data_type)i * theta_i);
            for(int j = i; j < n; j += m) {
                auto x = v[j] - v[j + mh];
                v[j] = v[j] + v[j + mh];
                v[j + mh] = w * x;
            }
        }
        theta *= 2;
    }
    for(int i = 0, j = 1; j < n - 1; ++j) {
        for(int k = n >> 1; k > (i ^= k); k >>= 1);
        if(j < i) {
            swap(v[i], v[j]);
        }
    }
    if(inv) {
        for(auto& x : v) x /= n;
    }
    return v;
}

matrix transpose(matrix a) {
    const int n = a.size(), m = a[0].size();
    matrix res(m, vector<data_type>(n));
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < m; ++j) {
            res[i][j] = a[j][i];
        }
    }
    return res;
}

matrix fft2d(matrix a, bool inv = false) {
    for(int t = 0; t < 2; ++t) {
        for(auto& v : a) {
            v = fft(move(v), inv);
        }
        a = transpose(move(a));
    }
    return a;
}

matrix conv2d(matrix a, matrix b) {
    const int nt = a.size() + b.size() - 1;
    const int mt = a[0].size() + b[0].size() - 1;
    int n = 1, m = 1;
    while(n < nt) n <<= 1;
    while(m < mt) m <<= 1;
    a.resize(n), b.resize(n);
    for(int i = 0; i < n; ++i) {
        a[i].resize(m);
        b[i].resize(m);
    }
    a = fft2d(move(a)), b = fft2d(move(b));
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < m; ++j) {
            a[i][j] *= b[i][j];
        }
    }
    return fft2d(move(a), true);
}

int main() {
    int n, m, K, l; cin >> n >> m >> K >> l;
    matrix dat(n, vector<data_type>(n));
    for(int i = 0; i < n; ++i) {
        string s; cin >> s;
        for(int j = 0; j < n; ++j) {
            if(s[j] == 'X') {
                dat[i][j] = data_type{1, 0};
            }
        }
    }
    string s; cin >> s;
    vector<vector<int>> tcnt(m, vector<int>(m));
    for(int y = 0, x = 0, i = 0; i < (int)s.size(); ++i) {
        if(s[i] == 'U') --y;
        if(s[i] == 'D') ++y;
        if(s[i] == 'R') ++x;
        if(s[i] == 'L') --x;
        tcnt[y][x]++;
    }
    matrix cnt(m, vector<data_type>(m));
    for(int i = 0; i < m; ++i) {
        for(int j = 0; j < m; ++j) {
            cnt[i][j] = data_type{(double)tcnt[i][j], 0};
        }
    }

    auto res = conv2d(cnt, dat);
    int ans = 0;
    for(int i = 0; i < m; ++i) {
        for(int j = 0; j < m; ++j) {
            const int val = (int)(real(res[i][j]) + 0.5);
            ans += val >= K;
        }
    }

    cout << ans << endl;
}
accuracy: 1
time_ms: 550
memory_kb: 61788
final_rank: 16

code_snippet: #include <bits/stdc++.h>
#define range(i, a, b) for (int i = (a); i < (b); i++)
#define rep(i, b) for (int i = 0; i < (b); i++)
#define all(a) (a).begin(), (a).end()
#define show(x) cerr << #x << " = " << (x) << endl;
#define int long long
using namespace std;

template <typename X, typename T>
auto vectors(X x, T a) {
	return vector<T>(x, a);
}

template <typename X, typename Y, typename Z, typename... Zs>
auto vectors(X x, Y y, Z z, Zs... zs) {
	auto cont = vectors(y, z, zs...);
	return vector<decltype(cont)>(x, cont);
}

template <typename T>
ostream& operator<<(ostream& os, vector<T>& v) {
	rep(i, v.size()) { os << v[i] << (i == v.size() - 1 ? "" : " "); }
	return os;
}
template <typename T>
istream& operator>>(istream& is, vector<T>& v) {
	for (T& x : v) { is >> x; }
	return is;
}

typedef complex<double> Complex;

vector<Complex> fft(vector<Complex> A, int n, int sgn = 1) {

	if (n == 1) return A;

	vector<Complex> f0, f1;
	for (int i = 0; i < (n / 2); i++) {
		f0.push_back(A[i * 2 + 0]);
		f1.push_back(A[i * 2 + 1]);
	}

	f0 = fft(f0, n / 2, sgn), f1 = fft(f1, n / 2, sgn);

	Complex zeta = Complex(cos(2.0 * M_PI / n), sin(2.0 * M_PI / n) * sgn);
	Complex pow_zeta = 1;

	for (int i = 0; i < n; i++) {
		A[i] = f0[i % (n / 2)] + pow_zeta * f1[i % (n / 2)];
		pow_zeta *= zeta;
	}
	return A;
}

vector<Complex> inv_fft(vector<Complex> A, int n) {
	auto ret = fft(A, n, -1);
	for (int i = 0; i < n; i++) { ret[i] /= n; }
	return ret;
}

vector<Complex> multiply(vector<Complex>& X, vector<Complex>& Y) {
	int n = 1;
	while (n < (X.size() + Y.size() + 1)) n *= 2;

	vector<Complex> ret;

	X.resize(n), Y.resize(n);
	X = fft(X, n, 1), Y = fft(Y, n, 1);

	for (int i = 0; i < n; i++) { ret.push_back(X[i] * Y[i]); }
	return inv_fft(ret, n);
}

signed main() {
	int n, m, k, l;
	cin >> n >> m >> k >> l;

	vector<string> b(n);
	rep(i, n) cin >> b[i];

	string s;
	cin >> s;

	vector<vector<int>> visited(m, vector<int>(m, 0));
	visited[0][0] = 0;
	int y = 0, x = 0;
	rep(i, s.size()) {
		if (s[i] == 'R') x++;
		if (s[i] == 'D') y++;
		if (s[i] == 'L') x--;
		if (s[i] == 'U') y--;
		visited[y][x]++;
	}

	vector<Complex> ca(m * m, Complex(0, 0)), cb;
	rep(i, n) rep(j, n) ca[i * m + j] = Complex(b[i][j] == 'X', 0);
	rep(i, m) rep(j, m) cb.emplace_back(visited[i][j]);

	int cnt = 0;
	auto ans = multiply(ca, cb);
	// show(ans.size())
	range(i, 0, m * m + 0) {
		// cout << ans[i] << endl;
		if (static_cast<int>(ans[i].real() + 0.5) >= k) cnt++;
	}
	cout << cnt << endl;
}
accuracy: 1
time_ms: 1140
memory_kb: 71352
final_rank: 17

code_snippet: #include <bits/stdc++.h>
#define range(i, a, b) for (int i = (a); i < (b); i++)
#define rep(i, b) for (int i = 0; i < (b); i++)
#define all(a) (a).begin(), (a).end()
#define show(x) cerr << #x << " = " << (x) << endl;
#define int long long
using namespace std;

template <typename X, typename T>
auto vectors(X x, T a) {
	return vector<T>(x, a);
}

template <typename X, typename Y, typename Z, typename... Zs>
auto vectors(X x, Y y, Z z, Zs... zs) {
	auto cont = vectors(y, z, zs...);
	return vector<decltype(cont)>(x, cont);
}

template <typename T>
ostream& operator<<(ostream& os, vector<T>& v) {
	rep(i, v.size()) { os << v[i] << (i == v.size() - 1 ? "" : " "); }
	return os;
}
template <typename T>
istream& operator>>(istream& is, vector<T>& v) {
	for (T& x : v) { is >> x; }
	return is;
}

typedef complex<double> Complex;

vector<Complex> fft(vector<Complex> A, int n, int sgn = 1) {

	if (n == 1) return A;

	vector<Complex> f0, f1;
	for (int i = 0; i < (n / 2); i++) {
		f0.push_back(A[i * 2 + 0]);
		f1.push_back(A[i * 2 + 1]);
	}

	f0 = fft(f0, n / 2, sgn), f1 = fft(f1, n / 2, sgn);

	Complex zeta = Complex(cos(2.0 * M_PI / n), sin(2.0 * M_PI / n) * sgn);
	Complex pow_zeta = 1;

	for (int i = 0; i < n; i++) {
		A[i] = f0[i % (n / 2)] + pow_zeta * f1[i % (n / 2)];
		pow_zeta *= zeta;
	}
	return A;
}

vector<Complex> inv_fft(vector<Complex> A, int n) {
	auto ret = fft(A, n, -1);
	for (int i = 0; i < n; i++) { ret[i] /= n; }
	return ret;
}

vector<Complex> multiply(vector<Complex>& X, vector<Complex>& Y) {
	int n = 1;
	while (n < (X.size() + Y.size() + 1)) n *= 2;

	vector<Complex> ret;

	X.resize(n), Y.resize(n);
	X = fft(X, n, 1), Y = fft(Y, n, 1);

	for (int i = 0; i < n; i++) { ret.push_back(X[i] * Y[i]); }
	return inv_fft(ret, n);
}

signed main() {
	int n, m, k, l;
	cin >> n >> m >> k >> l;

	vector<string> b(n);
	rep(i, n) cin >> b[i];

	string s;
	cin >> s;

	vector<vector<int>> visited(m, vector<int>(m, 0));
	visited[0][0] = 0;
	int y = 0, x = 0;
	rep(i, s.size()) {
		if (s[i] == 'R') x++;
		if (s[i] == 'D') y++;
		if (s[i] == 'L') x--;
		if (s[i] == 'U') y--;
		visited[y][x]++;
	}

	vector<Complex> ca(m * m, Complex(0, 0)), cb;
	rep(i, n) rep(j, n) ca[i * m + j] = Complex(b[i][j] == 'X', 0);
	rep(i, m) rep(j, m) cb.emplace_back(visited[i][j]);
	// ca.insert(ca.begin(), 0);
	// cb.insert(cb.begin(), 0);

	int cnt = 0;
	auto ans = multiply(ca, cb);
	// show(ans.size())
	range(i, 0, m * m + 0) {
		// cout << ans[i] << endl;
		if (ans[i].real() > k - 1e-9) cnt++;
	}
	cout << cnt << endl;
}
accuracy: 0.3793103448275862
time_ms: 540
memory_kb: 36688
final_rank: 20