Problem:
全宇宙生命ゲノムデータベース リターンズ
西暦2301年，宇宙連邦共和国の生命科学局では，宇宙生物のゲノム配列の研究を行っていた．近年の研究の結果，ゲノム配列に特定のパターンが何回現れるかが生物の性質に大きく影響することが分かってきた．
宇宙生物のゲノム配列は英大文字からなる文字列で表される．研究員たちはゲノム配列の中に，ある特定のパターンが何回現れるかを数え上げることにした．しかしながら，宇宙生物のゲノム配列は非常に長いため，後述する方法で繰り返しがある部分文字列を圧縮してデータベースに保存している．
あなたの仕事は圧縮されたゲノム配列
S
から文字列
Q
の出現回数を数え上げるプログラムを作成することである．ただし，
Q
の出現は，開始位置さえ異なっていれば，重なっている部分があっても別の出現として数える．例えば， MISSISSIPPI に ISSI は 2 回出現する．
ゲノム配列の圧縮方法は以下のBNFで定義される．
<Genome> ::= <Letter> | <Number> <Letter> | <Number> ( <Genome> ) | <Genome> <Genome>
<Letter> ::= 'A' | 'B' | … | 'Z'
<Number> ::= <Digit> | <Number> '0' | <Number> <Digit>
<Digit> ::= '1' | '2' | … | '9'
ここで，文字列の前に付けられる整数はその文字列がその回数だけ繰り返されることを表す．例えば，5A は AAAAA を表し，2(AB) は ABAB を表す．整数の直後に括弧がない場合は，その直後の1文字のみが繰り返される．例えば，2AB は AAB を表す．繰り返しは多重にネストすることが可能で，2(2(AB)C) は 2(ABABC) と同じであり，ABABCABABC を表す．
Input
入力は最大で 50 個のデータセットから構成される．各データセットは次の形式で表される．
S
Q
各データセットの1行目は，圧縮されたゲノム配列を表す文字列
S
である．
S
は上記のBNFに従い，その長さは
1
以上
3 000
文字以下である．また，
S
を展開した元のゲノム配列の長さは
10
18
以下である．各データセットの2行目は数え上げる対象となる文字列
Q
である．
Q
は英大文字からなり，長さは
1
以上
3 000
文字以下である．
入力の終了は '#' の1文字だけを含む行で表される．
Output
各データセットについて，
S
を展開した文字列に
Q
が何回現れるかを出力せよ．
Sample Input
MI2(2SI)2PI
ISSI
100(100(JAG))
JAG
1000000000000000000A
AAAAA
#
Output for the Sample Input
2
10000
999999999999999996

Submitted solutions:

code_snippet: // C++ includes used for precompiling -*- C++ -*-
// Copyright (C) 2003-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://w...content-available-to-author-only...u.org/licenses/>.
/** @file stdc++.h
 *  This is an implementation file for a precompiled header.
 */
// 17.4.1.2 Headers
// C
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#if __cplusplus >= 201103L
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cwchar>
#include <cwctype>
#endif
// C++
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#if __cplusplus >= 201103L
#include <array>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <type_traits>
#include <typeindex>
#include <unordered_map>
#include <unordered_set>

#endif
using namespace std;
using ll = long long;
using ull = unsigned long long;
using uint = unsigned int;
#define rep(i, n) for (int i = 0; i < n; i++)
#define all(v) v.begin(), v.end()
template <class T, class U>
inline bool chmax(T &a, U b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
template <class T, class U>
inline bool chmin(T &a, U b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template <class T>
inline void compress(vector<T> &a) {
    sort(a.begin(), a.end());
    a.erase(unique(a.begin(), a.end()), a.end());
}
template <class T>
T rand(T l, T r) {
    static mt19937 mt(random_device{}());
    // [l, r)
    if constexpr (is_integral_v<T>) {
        return uniform_int_distribution<T>(l, r - 1)(mt);
    } else if constexpr (is_floating_point_v<T>) {
        return uniform_real_distribution<T>(l, r)(mt);
    }
}
constexpr int INF = 1001001001;
constexpr ll llINF = 3000000000000000010;
struct linear_sieve {
    vector<int> least_factor, prime_list;
    linear_sieve(int n) : least_factor(n + 1, 0) {
        for (int i = 2; i <= n; i++) {
            if (least_factor[i] == 0) {
                least_factor[i] = i;
                prime_list.push_back(i);
            }
            for (int p : prime_list) {
                if (ll(i) * p > n || p > least_factor[i]) break;
                least_factor[i * p] = p;
            }
        }
    }
};
template <int modulo>
struct modint {
    int x;
    modint() : x(0) {}
    modint(int64_t y) : x(y >= 0 ? y % modulo : (modulo - (-y) % modulo) % modulo) {}
    modint &operator+=(const modint &p) {
        if ((x += p.x) >= modulo) x -= modulo;
        return *this;
    }
    modint &operator-=(const modint &p) {
        if ((x += modulo - p.x) >= modulo) x -= modulo;
        return *this;
    }
    modint &operator*=(const modint &p) {
        x = (int)(1LL * x * p.x % modulo);
        return *this;
    }
    modint &operator/=(const modint &p) {
        *this *= p.inv();
        return *this;
    }
    modint operator-() const { return modint(-x); }
    modint operator+(const modint &p) const { return modint(*this) += p; }
    modint operator-(const modint &p) const { return modint(*this) -= p; }
    modint operator*(const modint &p) const { return modint(*this) *= p; }
    modint operator/(const modint &p) const { return modint(*this) /= p; }
    bool operator==(const modint &p) const { return x == p.x; }
    bool operator!=(const modint &p) const { return x != p.x; }
    modint inv() const {
        int a = x, b = modulo, u = 1, v = 0, t;
        while (b > 0) {
            t = a / b;
            swap(a -= t * b, b);
            swap(u -= t * v, v);
        }
        return modint(u);
    }
    modint pow(int64_t n) const {
        modint ret(1), mul(x);
        while (n > 0) {
            if (n & 1) ret *= mul;
            mul *= mul;
            n >>= 1;
        }
        return ret;
    }
    friend ostream &operator<<(ostream &os, const modint &p) { return os << p.x; }
    friend istream &operator>>(istream &is, modint &a) {
        int64_t t;
        is >> t;
        a = modint<modulo>(t);
        return (is);
    }
    int val() const { return x; }
    static constexpr int mod() { return modulo; }
    static constexpr int half() { return (modulo + 1) >> 1; }
};
ll extgcd(ll a, ll b, ll &x, ll &y) {
    // ax+by=gcd(|a|,|b|)
    if (a < 0 || b < 0) {
        ll d = extgcd(abs(a), abs(b), x, y);
        if (a < 0) x = -x;
        if (b < 0) y = -y;
        return d;
    }
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    ll d = extgcd(b, a % b, y, x);
    y -= a / b * x;
    return d;
}
template <typename T>
struct Binomial {
    vector<T> inv, fact, factinv;
    Binomial(int n) {
        inv.resize(n + 1);
        fact.resize(n + 1);
        factinv.resize(n + 1);
        inv[0] = fact[0] = factinv[0] = 1;
        for (int i = 1; i <= n; i++) fact[i] = fact[i - 1] * i;
        factinv[n] = fact[n].inv();
        inv[n] = fact[n - 1] * factinv[n];
        for (int i = n - 1; i >= 1; i--) {
            factinv[i] = factinv[i + 1] * (i + 1);
            inv[i] = fact[i - 1] * factinv[i];
        }
    }
    T C(int n, int r) {
        if (n < 0 || n < r || r < 0) return 0;
        return fact[n] * factinv[n - r] * factinv[r];
    }
    T P(int n, int r) {
        if (n < 0 || n < r || r < 0) return 0;
        return fact[n] * factinv[n - r];
    }
    T H(int n, int r) {
        if (n == 0 && r == 0) return 1;
        if (n < 0 || r < 0) return 0;
        return r == 0 ? 1 : C(n + r - 1, r);
    }
};
template <class T>
vector<T> dijkstra(vector<vector<pair<int, T>>> &g, vector<int> start) {
    using P = pair<T, int>;
    vector<T> dp(g.size(), numeric_limits<T>::max());
    priority_queue<P, vector<P>, greater<P>> que;
    for (int s : start) {
        dp[s] = 0;
        que.push({0, s});
    }
    while (que.size()) {
        auto [d, v] = que.top();
        que.pop();
        if (dp[v] != d) continue;
        for (auto [u, c] : g[v]) {
            if (chmin(dp[u], d + c)) que.push({dp[u], u});
        }
    }
    return dp;
}

vector<int> BFS01(vector<vector<pair<int, int>>> &g, vector<int> start) {
    vector<int> dp(g.size(), numeric_limits<int>::max());
    deque<int> que;
    for (int s : start) {
        dp[s] = 0;
        que.push_front(s);
    }
    while (que.size()) {
        auto v = que.front();
        que.pop_front();
        for (auto [u, c] : g[v]) {
            if (chmin(dp[u], dp[v] + c)) {
                if (c == 0)
                    que.push_front(u);
                else
                    que.push_back(u);
            }
        }
    }
    return dp;
}
template <typename T, typename U>
inline istream &operator>>(istream &is, pair<T, U> &rhs) {
    return is >> rhs.first >> rhs.second;
}
template <typename T>
inline istream &operator>>(istream &is, vector<T> &v) {
    for (auto &e : v) is >> e;
    return is;
}
template <typename T, typename U>
inline ostream &operator<<(ostream &os, const pair<T, U> &rhs) {
    return os << rhs.first << " " << rhs.second;
}
template <typename T>
inline ostream &operator<<(ostream &os, const vector<T> &v) {
    for (auto itr = v.begin(), end_itr = v.end(); itr != end_itr;) {
        os << *itr;
        if (++itr != end_itr) os << " ";
    }
    return os;
}

struct UnionFind {
    vector<int> par, siz;
    UnionFind(int x) {
        par.resize(x);
        siz.resize(x);
        for (int i = 0; i < x; i++) {
            par[i] = i;
            siz[i] = 1;
        }
    }
    int find(int x) {
        if (par[x] == x) return x;
        return par[x] = find(par[x]);
    }
    bool unite(int x, int y) {
        x = find(x), y = find(y);
        if (x == y) return false;
        if (siz[x] < siz[y]) swap(x, y);
        par[y] = x;
        siz[x] += siz[y];

        return true;
    }
    bool same(int x, int y) { return find(x) == find(y); }
    int size(int x) { return siz[find(x)]; }
};
template <class T>
struct BIT {
    // 1-indexed
    int n, beki = 1;
    vector<T> bit;
    BIT(int x) {
        bit.resize(x + 1, 0);
        n = x;
        while (beki * 2 <= n) beki *= 2;
    }
    T sum(int i) {
        T res = 0;
        while (i > 0) {
            res += bit[i];
            i -= i & -i;
        }
        return res;
    }
    T sum(int l, int r) {
        //[l,r]
        return sum(r) - (l == 0 ? 0 : sum(l - 1));
    }
    void add(int i, T x) {
        while (i <= n) {
            bit[i] += x;
            i += i & -i;
        }
    }
    int lowerbound(T w) {
        if (w <= 0) return 0;
        int x = 0;
        for (int k = beki; k > 0; k >>= 1) {
            if (x + k <= n && bit[x + k] < w) {
                w -= bit[x + k];
                x += k;
            }
        }
        return x + 1;
    }
};

#include <algorithm>
#include <cassert>
#include <numeric>
#include <string>
#include <vector>

namespace atcoder {

namespace internal {

std::vector<int> sa_naive(const std::vector<int>& s) {
    int n = int(s.size());
    std::vector<int> sa(n);
    std::iota(sa.begin(), sa.end(), 0);
    std::sort(sa.begin(), sa.end(), [&](int l, int r) {
        if (l == r) return false;
        while (l < n && r < n) {
            if (s[l] != s[r]) return s[l] < s[r];
            l++;
            r++;
        }
        return l == n;
    });
    return sa;
}

std::vector<int> sa_doubling(const std::vector<int>& s) {
    int n = int(s.size());
    std::vector<int> sa(n), rnk = s, tmp(n);
    std::iota(sa.begin(), sa.end(), 0);
    for (int k = 1; k < n; k *= 2) {
        auto cmp = [&](int x, int y) {
            if (rnk[x] != rnk[y]) return rnk[x] < rnk[y];
            int rx = x + k < n ? rnk[x + k] : -1;
            int ry = y + k < n ? rnk[y + k] : -1;
            return rx < ry;
        };
        std::sort(sa.begin(), sa.end(), cmp);
        tmp[sa[0]] = 0;
        for (int i = 1; i < n; i++) {
            tmp[sa[i]] = tmp[sa[i - 1]] + (cmp(sa[i - 1], sa[i]) ? 1 : 0);
        }
        std::swap(tmp, rnk);
    }
    return sa;
}

template <int THRESHOLD_NAIVE = 10, int THRESHOLD_DOUBLING = 40>
std::vector<int> sa_is(const std::vector<int>& s, int upper) {
    int n = int(s.size());
    if (n == 0) return {};
    if (n == 1) return {0};
    if (n == 2) {
        if (s[0] < s[1]) {
            return {0, 1};
        } else {
            return {1, 0};
        }
    }
    if (n < THRESHOLD_NAIVE) {
        return sa_naive(s);
    }
    if (n < THRESHOLD_DOUBLING) {
        return sa_doubling(s);
    }

    std::vector<int> sa(n);
    std::vector<bool> ls(n);
    for (int i = n - 2; i >= 0; i--) {
        ls[i] = (s[i] == s[i + 1]) ? ls[i + 1] : (s[i] < s[i + 1]);
    }
    std::vector<int> sum_l(upper + 1), sum_s(upper + 1);
    for (int i = 0; i < n; i++) {
        if (!ls[i]) {
            sum_s[s[i]]++;
        } else {
            sum_l[s[i] + 1]++;
        }
    }
    for (int i = 0; i <= upper; i++) {
        sum_s[i] += sum_l[i];
        if (i < upper) sum_l[i + 1] += sum_s[i];
    }

    auto induce = [&](const std::vector<int>& lms) {
        std::fill(sa.begin(), sa.end(), -1);
        std::vector<int> buf(upper + 1);
        std::copy(sum_s.begin(), sum_s.end(), buf.begin());
        for (auto d : lms) {
            if (d == n) continue;
            sa[buf[s[d]]++] = d;
        }
        std::copy(sum_l.begin(), sum_l.end(), buf.begin());
        sa[buf[s[n - 1]]++] = n - 1;
        for (int i = 0; i < n; i++) {
            int v = sa[i];
            if (v >= 1 && !ls[v - 1]) {
                sa[buf[s[v - 1]]++] = v - 1;
            }
        }
        std::copy(sum_l.begin(), sum_l.end(), buf.begin());
        for (int i = n - 1; i >= 0; i--) {
            int v = sa[i];
            if (v >= 1 && ls[v - 1]) {
                sa[--buf[s[v - 1] + 1]] = v - 1;
            }
        }
    };

    std::vector<int> lms_map(n + 1, -1);
    int m = 0;
    for (int i = 1; i < n; i++) {
        if (!ls[i - 1] && ls[i]) {
            lms_map[i] = m++;
        }
    }
    std::vector<int> lms;
    lms.reserve(m);
    for (int i = 1; i < n; i++) {
        if (!ls[i - 1] && ls[i]) {
            lms.push_back(i);
        }
    }

    induce(lms);

    if (m) {
        std::vector<int> sorted_lms;
        sorted_lms.reserve(m);
        for (int v : sa) {
            if (lms_map[v] != -1) sorted_lms.push_back(v);
        }
        std::vector<int> rec_s(m);
        int rec_upper = 0;
        rec_s[lms_map[sorted_lms[0]]] = 0;
        for (int i = 1; i < m; i++) {
            int l = sorted_lms[i - 1], r = sorted_lms[i];
            int end_l = (lms_map[l] + 1 < m) ? lms[lms_map[l] + 1] : n;
            int end_r = (lms_map[r] + 1 < m) ? lms[lms_map[r] + 1] : n;
            bool same = true;
            if (end_l - l != end_r - r) {
                same = false;
            } else {
                while (l < end_l) {
                    if (s[l] != s[r]) {
                        break;
                    }
                    l++;
                    r++;
                }
                if (l == n || s[l] != s[r]) same = false;
            }
            if (!same) rec_upper++;
            rec_s[lms_map[sorted_lms[i]]] = rec_upper;
        }

        auto rec_sa =
            sa_is<THRESHOLD_NAIVE, THRESHOLD_DOUBLING>(rec_s, rec_upper);

        for (int i = 0; i < m; i++) {
            sorted_lms[i] = lms[rec_sa[i]];
        }
        induce(sorted_lms);
    }
    return sa;
}

}  // namespace internal

std::vector<int> suffix_array(const std::vector<int>& s, int upper) {
    assert(0 <= upper);
    for (int d : s) {
        assert(0 <= d && d <= upper);
    }
    auto sa = internal::sa_is(s, upper);
    return sa;
}

template <class T> std::vector<int> suffix_array(const std::vector<T>& s) {
    int n = int(s.size());
    std::vector<int> idx(n);
    iota(idx.begin(), idx.end(), 0);
    sort(idx.begin(), idx.end(), [&](int l, int r) { return s[l] < s[r]; });
    std::vector<int> s2(n);
    int now = 0;
    for (int i = 0; i < n; i++) {
        if (i && s[idx[i - 1]] != s[idx[i]]) now++;
        s2[idx[i]] = now;
    }
    return internal::sa_is(s2, now);
}

std::vector<int> suffix_array(const std::string& s) {
    int n = int(s.size());
    std::vector<int> s2(n);
    for (int i = 0; i < n; i++) {
        s2[i] = s[i];
    }
    return internal::sa_is(s2, 255);
}

template <class T>
std::vector<int> lcp_array(const std::vector<T>& s,
                           const std::vector<int>& sa) {
    int n = int(s.size());
    assert(n >= 1);
    std::vector<int> rnk(n);
    for (int i = 0; i < n; i++) {
        rnk[sa[i]] = i;
    }
    std::vector<int> lcp(n - 1);
    int h = 0;
    for (int i = 0; i < n; i++) {
        if (h > 0) h--;
        if (rnk[i] == 0) continue;
        int j = sa[rnk[i] - 1];
        for (; j + h < n && i + h < n; h++) {
            if (s[j + h] != s[i + h]) break;
        }
        lcp[rnk[i] - 1] = h;
    }
    return lcp;
}

std::vector<int> lcp_array(const std::string& s, const std::vector<int>& sa) {
    int n = int(s.size());
    std::vector<int> s2(n);
    for (int i = 0; i < n; i++) {
        s2[i] = s[i];
    }
    return lcp_array(s2, sa);
}

template <class T> std::vector<int> z_algorithm(const std::vector<T>& s) {
    int n = int(s.size());
    if (n == 0) return {};
    std::vector<int> z(n);
    z[0] = 0;
    for (int i = 1, j = 0; i < n; i++) {
        int& k = z[i];
        k = (j + z[j] <= i) ? 0 : std::min(j + z[j] - i, z[i - j]);
        while (i + k < n && s[k] == s[i + k]) k++;
        if (j + z[j] < i + z[i]) j = i;
    }
    z[0] = n;
    return z;
}

std::vector<int> z_algorithm(const std::string& s) {
    int n = int(s.size());
    std::vector<int> s2(n);
    for (int i = 0; i < n; i++) {
        s2[i] = s[i];
    }
    return z_algorithm(s2);
}

}  // namespace atcoder

using mint = modint<998244353>;
using State = string::const_iterator;
string target;
int len;
struct S {
    // 前3000文字+後ろ3000文字、個数
    string pre, suf;
    ll cnt;
};
S merge(S a, S b) {
    string str = target + a.suf + b.pre;
    S res;
    res.cnt = a.cnt + b.cnt;
    res.pre = a.pre;
    if (res.pre.size() < len - 1) {
        res.pre += b.pre;
        if (res.pre.size() > len - 1) {
            res.pre = res.pre.substr(0, len - 1);
        }
    }
    res.suf = b.suf;
    if (res.suf.size() < len - 1) {
        res.suf = a.suf + b.suf;
        if (res.suf.size() > len - 1) {
            res.suf = res.suf.substr(res.suf.size() - (len - 1));
        }
    }

    auto z = atcoder::z_algorithm(str);
    for (int i = target.size(); i + len <= str.size(); i++) {
        if (z[i] >= len) res.cnt++;
    }
    return res;
}

S calc(ll num, S g) {
    S res = g;
    num -= 1;
    while (num) {
        if (num & 1) {
            res = merge(res, g);
        }
        g = merge(g, g);
        num >>= 1;
    }
    return res;
}
S genome(State &i);
S letter(State &i);
ll number(State &i);
S genome(State &i) {
    S res;
    if (isdigit(*i)) {
        ll num = number(i);
        if (*i == '(') {
            i++;
            res = calc(num, genome(i));
            i++;
        } else {
            res = calc(num, letter(i));
        }
    } else
        res = letter(i);
    if (*i == ')') return res;
    return merge(res, genome(i));
}
S letter(State &i) {
    assert(isupper(*i));
    S res;
    if (len == 1) {
        res.pre = res.suf = "";
        res.cnt = (target[0] == *i);
    } else {
        res.pre += char(*i);
        res.suf += char(*i);
        res.cnt = 0;
    }
    i++;
    return res;
}
ll number(State &i) {
    ll res = 0;
    while (isdigit(*i)) {
        res = res * 10 + (*i - '0');
        i++;
    }
    return res;
}
void solve() {
    string s;
    cin >> s;
    if (s == "#") exit(0);
    cin >> target;
    s += ")";
    len = target.size();
    State it = s.begin();
    cout << genome(it).cnt << endl;
}
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int t = 1;
    // cin >> t;
    while (1) solve();
}
accuracy: 1
time_ms: 3200
memory_kb: 5056
final_rank: 13

code_snippet: #include <bits/stdc++.h>
#include <stdlib.h>
using namespace std;
#define rep(i, a, n) for(ll i = a; i < n; i++)
#define rrep(i, a, n) for(ll i = a; i >= n; i--)
#define ll long long
#define pii pair<int, int>
#define pll pair<ll, ll>
constexpr ll MOD = 998244353;
constexpr int IINF = 1001001001;
constexpr ll INF = 1LL<<60;
template<class t,class u> void chmax(t&a,u b){if(a<b)a=b;}
template<class t,class u> void chmin(t&a,u b){if(b<a)a=b;}

vector<int> Z_algorithm(string S) {
	int c = 0, n = S.size();
	vector<int> Z(n, 0);
	for (int i = 1; i < n; i++) {
		int l = i - c;
		if (i + Z[l] < c + Z[c]) {
			Z[i] = Z[l];
		}
		else {
			int j = max(0, c + Z[c] - i);
			while (i + j < n && S[j] == S[i + j])j++;
			Z[i] = j;
			c = i;
		}
	}
	Z[0] = n;
	return Z;
}

string t;

struct X {
    string left, right;
    ll cnt;

    X (): left(""),right(""),cnt(0){}

    X (string s) {
        // cerr << s << endl << endl;
        ll n = s.size();
        ll m = t.size();
        left = right = s;
        left = left.substr(0,min(n,m-1));
        right = right.substr(max(0LL,n-(m-1)),min(n,m-1));
        vector<int> vec = Z_algorithm(t+s);
        ll now = m;
        cnt = 0;
        while(now < n+m){
            if(vec[now] >= m) cnt++;
            now++;
        }
    }
};

X merge(X a, X b){
    ll m = t.size();
    X res;
    vector<int> vec = Z_algorithm(t+a.right+b.left);
    res.cnt = a.cnt+b.cnt;
    ll sz = min((ll)a.left.size()+(ll)b.left.size(), m-1);
    res.left = a.left.size() == m-1 ? a.left: (a.left+b.left).substr(0,sz);
    res.right = b.right.size() == m-1 ? b.right: (a.right+b.right).substr(a.right.size()+b.right.size()-sz,sz);

    ll now = m;
    while(now < vec.size()){
        if(vec[now] >= m) res.cnt++;
        now++;
    }
    return res;
}

X multiple (X a, ll num) {
    X res;
    X now = a;
    while(num){
        if(num&1) res = merge(res, now);
        now = merge(now, now);
        num >>= 1;
    }
    return res;
}

ll is_str(char x){
    return ('A' <= x && x <= 'Z');
}

ll is_num(char x){
    return ('0' <= x && x <= '9');
}

int main() {
    while(true){
        string s; cin >> s;
        ll n = s.size();
        if(s == "#") break;
        cin >> t;
        auto solve = [&](auto solve, ll l, ll r) -> X {
            // cerr << l << " " << r << endl;
            if(is_str(s[l])){
                ll rr = l;
                while(rr < r && is_str(s[rr])) rr++;
                // cerr << l << " " << rr << endl;
                if(rr == r) return X(s.substr(l,rr-l));
                else return merge(X(s.substr(l,rr-l)),solve(solve, rr, r));
            }
            else{
                ll rr = l;
                while(rr < r && is_num(s[rr])) rr++;
                if(is_str(s[rr])){
                    if(rr+1 == r) return multiple(X(s.substr(rr,1)), stol(s.substr(l,rr-l)));
                    else return merge(multiple(X(s.substr(rr,1)),stol(s.substr(l,rr-l))),solve(solve, rr+1, r));
                }else{
                    ll rrr = rr+1;
                    ll now = 1;
                    while(now != 0){
                        if(s[rrr] == '(') now++;
                        if(s[rrr] == ')') now--;
                        rrr++;
                    }
                    if(rrr == r) return multiple(solve(solve,rr+1,rrr-1),stol(s.substr(l,rr-l)));
                    else return merge(multiple(solve(solve,rr+1,rrr-1),stol(s.substr(l,rr-l))),solve(solve, rrr, r));
                }
            }
        };
        cout << solve(solve, 0, n).cnt << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 1500
memory_kb: 4224
final_rank: 4

code_snippet: #include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <algorithm>
#include <utility>
#include <tuple>
#include <cstdint>
#include <cstdio>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <deque>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <cctype>
#include <climits>
#include <functional>
#include <cassert>
#include <numeric>
#define rep(i, n) for(int i = 0; i < (n); i++)
#define per(i, n) for(int i = (n) - 1; i >= 0; i--)
using ll = long long;
#define vi vector<int>
#define vvi vector<vi>
#define vl vector<ll>
#define pii pair<int, int>
#define pll pair<ll, ll>
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
constexpr int mod = 1000000007;
using namespace std;
template<class T, class U>
bool chmax(T &a, const U &b){ return a < b ? (a = b, 1) : 0; }
template<class T, class U>
bool chmin(T &a, const U &b){ return a > b ? (a = b, 1) : 0; }
vector<int> z_algo(const string &s){
  int n = s.size();
  vector<int> z(n);
  z[0] = n;
  int i = 1, j = 0;
  while(i < n){
    while(i + j < n && s[j] == s[i + j]) j++;
    z[i] = j;
    if(!j){
      i++;
      continue;
    }
    int k = 1;
    while(k < j && z[k] + k < j) z[i + k++] = z[k];
    i += k;
    j -= k;
  }
  return z;
}
struct Data {
  string left,right;
  ll val;
};
string s,t;
int n,m;
int find_both(const string &l, const string &r){
  const auto z = z_algo(t + '$' + l + r);
  int res = 0;
  for(int i = m + 1; i < (int)z.size(); i++){
    if(z[i] >= m) res++;
  }
  return res;
}
Data merge(Data l, const Data &r){
  l.val += r.val;
  l.val += find_both(l.right, r.left);
  if((int)l.left.size() < m-1) l.left += r.left;
  if((int)r.right.size() < m-1) l.right += r.right;
  else l.right = r.right;
  if((int)l.left.size() >= m) l.left.resize(m-1);
  if((int)l.right.size() >= m) l.right.erase(l.right.begin(), l.right.end()-(m-1));
  return l;
}
Data multiply(const Data &d, ll num){
  if(num == 1) return d;
  Data two = d;
  Data res = {};
  while(num){
    if(num & 1) res = merge(res, two);
    two = merge(two, two);
    num >>= 1;
  }
  return res;
}
Data dfs(const int l, const int r){
  if(l >= r) return {};
  int i = l;
  ll v = 0;
  while('0' <= s[i] && s[i] <= '9'){
    v = v * 10 + (s[i] - '0');
    i++;
  }
  chmax(v, 1);
  const int bs = i;
  if(s[i] == '('){
    int cnt = 0;
    i++;
    while(cnt >= 0){
      if(s[i] == '(') cnt++;
      if(s[i] == ')') cnt--;
      i++;
    }
    auto L = dfs(bs+1, i-1);
    auto R = dfs(i, r);
    return merge(multiply(L, v), R);
  }else{
    Data d;
    if(m-1 >= 1){
      d.left += s[i];
      d.right += s[i];
    }
    d.val = (m == 1 && t[0] == s[i]);
    auto S = dfs(i+1, r);
    return merge(multiply(d, v), S);
  }
}
int main(){
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  while(true){
    cin >> s;
    if(s == "#") break;
    cin >> t;
    n = s.size();
    m = t.size();
    auto res = dfs(0, n);
    cout << res.val << "\n";
  }
}
accuracy: 1
time_ms: 1060
memory_kb: 4864
final_rank: 3

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <stack>
#include <set>
#include <unordered_set>
#include <map>
#include <iomanip>
#include <unordered_map>
#include <functional>
#include <atcoder/all>
using namespace std;
using namespace atcoder;
using pii = pair<int, int>;
using vi = vector<int>;
using vii = vector<pii>;
using ll = long long;
using pll = pair<ll, ll>;
using vl = vector<ll>;
using vll = vector<pll>;
using mint = modint998244353;
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

struct node {
    ll cnt = 0;
    vector<pair<int,bool>>l,r;

    node(int siz)
    {
        l.assign(siz+1,{-1,false});
        r.assign(siz+1,{-1,false});
        l[siz] = {siz,false};
        r[0] = {0,false};
    }
};

node proc(const string& q, int siz, char c)
{
    node res(siz);

    if(q.size()==1 && q[0]==c) {
        res.cnt = 1;
        return res;
    }

    for(int i=0; i<siz; i++) {
        if(c==q[i]) {
            res.l[i] = {i+1, true};
            res.r[i+1] ={i, true};
        }
    }

    return res;
}

node add(const string& q, int siz, node a, node b)
{
    /*
    cerr << "BEFORE" << endl;
    cerr << a.cnt << endl;
    for(auto [lnxt, flag]:a.l) cerr << lnxt << "xo"[flag] << " ";
    cerr << endl;
    for(auto [rnxt, flag]:a.r) cerr << rnxt << "xo"[flag] << " ";
    cerr << endl; 
    cerr << b.cnt << endl;
    for(auto [lnxt, flag]:b.l) cerr << lnxt << "xo"[flag] << " ";
    cerr << endl;
    for(auto [rnxt, flag]:b.r) cerr << rnxt << "xo"[flag] << " ";
    cerr << endl; 
    */
    node res(siz);

    res.cnt = a.cnt + b.cnt;
    for(int i=0; i<=siz; i++)
    {
        if(i!=siz && a.l[i].first!=-1) {
            if(a.l[i].second) {
                auto [lnxt, flag] = b.l[a.l[i].first];
                if(i==0 && lnxt==siz) res.cnt++;
                else res.l[i] = {lnxt, flag};
            }
            else {
                res.l[i] = a.l[i];
            }
        }
        if(i!=0 && b.r[i].first!=-1) {
            if(b.r[i].second) {
                auto [rnxt, flag] = a.r[b.r[i].first];
                if(rnxt==0 && i==siz) {
                    if(!flag) res.cnt++;
                }
                else res.r[i] = {rnxt, flag};
            }
            else {
                res.r[i] = b.r[i];
            }
        }
        // ###AA + BB## (Q=AABB)
        if(a.r[i].second==false && a.r[i].first==0 && b.l[i].second==false && b.l[i].first==siz) res.cnt++;
    }
    /*
    cerr << "AFTER" << endl;
    cerr << res.cnt << endl;
    for(auto [lnxt, flag]:res.l) cerr << lnxt << "xo"[flag] << " ";
    cerr << endl;
    for(auto [rnxt, flag]:res.r) cerr << rnxt << "xo"[flag] << " ";
    cerr << endl; 
    */
    return res;
}

node loop(const string& q, int siz, const node& one, ll lcnt)
{
    node res(siz);
    for(int i=0; i<=siz; i++)
    {
        res.l[i]={i,true};
        res.r[i]={i,true};
    }

    node pow2 = one;

    while(lcnt)
    {
        //cerr << "LOOP" << endl;
        if(lcnt & 1) res = add(q,siz,res,pow2);
        //cerr << "POW2" << endl;
        pow2 = add(q,siz,pow2,pow2);
        lcnt >>= 1;
    }

    return res;
}


node dfs(const string& s, const string& q, const vl& rp, int l_lim, int r_lim, int siz) {
    node res(siz);
    for(int i=0; i<=siz; i++)
    {
        res.l[i]={i,true};
        res.r[i]={i,true};
    }
    
    int l = l_lim;
    while(l < r_lim) {
        node diff(siz);

        if('0' <= s[l] && s[l] <= '9') {
            ll nl = l, nr = l;
            while('0' <= s[nr] && s[nr] <= '9') nr++;
            ll cnt = stoll(s.substr(nl,nr));

            node di(siz);
            if(s[nr]=='(') {
                //cerr << "[LOOP=" << cnt << "]" << s.substr(nr,rp[nr]-nr) << endl;
                di = dfs(s,q,rp,nr+1,rp[nr]-1,siz);
                l = rp[nr];
            }

            else {
                //cerr << "[LOOP=" << cnt << "]" << s.substr(nr,nr+1-nr) << endl;
                di = dfs(s,q,rp,nr,nr+1,siz);
                l = nr+1;
            }
            diff = loop(q,siz,di,cnt);
        }
        else {
            //cerr << "[PROC]" << s.substr(l,l+1-l) << endl;
            diff = proc(q,siz,s[l]);
            l = l+1;
        }
        /*
        cerr << "[BEFORE]" << endl;
        cerr << res.cnt << endl;
        for(auto [lnxt, flag]:res.l) cerr << lnxt << "xo"[flag] << " ";
        cerr << endl;
        for(auto [rnxt, flag]:res.r) cerr << rnxt << "xo"[flag] << " ";
        cerr << endl;
        cerr << diff.cnt << endl;
        for(auto [lnxt, flag]:diff.l) cerr << lnxt << "xo"[flag] << " ";
        cerr << endl;
        for(auto [rnxt, flag]:diff.r) cerr << rnxt << "xo"[flag] << " ";
        cerr << endl;
        */
        //cerr << "MAIN" << endl; 
        res = add(q,siz,res,diff);
        /*
        cerr << "[RESULT]" << endl;
        cerr << res.cnt << endl;
        for(auto [lnxt, flag]:res.l) cerr << lnxt << "xo"[flag] << " ";
        cerr << endl;
        for(auto [rnxt, flag]:res.r) cerr << rnxt << "xo"[flag] << " ";
        cerr << endl; 
        */
    }
    // cerr << "[END]" << "[" << l_lim << " " << r_lim << ")" << endl;
    return res;
}

int main() {
    while(1) {
        string s,q;
        cin >> s;
        if(s=="#") break;
        cin >> q;

        vl rp(s.size(),-1), stk;
        for(int i=0; i<s.size(); i++) {
            if(s[i]=='(') {
                stk.push_back(i);
            }
            if(s[i]==')') {
                rp[*stk.rbegin()] = i+1;
                stk.pop_back();
            }
        }

        node ans = dfs(s,q,rp,0,s.size(),q.size());
        cout << ans.cnt << endl;
    }
}
accuracy: 1
time_ms: 2000
memory_kb: 11300
final_rank: 8

code_snippet: // AOJ #2949 The Genome Database of All Space Life Returns
// 2025.3.11

#include <bits/stdc++.h>
using namespace std;
using ull = unsigned long long;

int m;
string q;
vector<vector<int>> nxt;

void buildAutomaton() {
    m = q.size();
    vector<int> pi(m, 0);
    for (int i = 1, j = 0; i < m; i++) {
        while(j && q[i] != q[j]) j = pi[j-1];
        if(q[i] == q[j]) j++;
        pi[i] = j;
    }
    nxt.assign(m+1, vector<int>(26, 0));
    for (int i = 0; i <= m; i++) {
        for (int c = 0; c < 26; c++) {
            if(i < m && q[i] - 'A' == c) nxt[i][c] = i + 1;
            else if(i == 0) nxt[i][c] = 0;
            else nxt[i][c] = nxt[pi[i-1]][c];
        }
    }
}

struct Seg {
    vector<int> t;
    vector<ull> o;
    Seg() {}
};

Seg identity() {
    Seg id;
    id.t.resize(m+1);
    id.o.resize(m+1);
    for (int i = 0; i <= m; i++){
        id.t[i] = i;
        id.o[i] = 0ULL;
    }
    return id;
}

Seg comp(const Seg &a, const Seg &b) {
    Seg r;
    r.t.resize(m+1);
    r.o.resize(m+1);
    for (int i = 0; i <= m; i++){
        int j = a.t[i];
        r.t[i] = b.t[j];
        r.o[i] = a.o[i] + b.o[j];
    }
    return r;
}

Seg lit(char c) {
    Seg r;
    r.t.resize(m+1);
    r.o.resize(m+1);
    int ch = c - 'A';
    for (int i = 0; i <= m; i++){
        int j = nxt[i][ch];
        r.t[i] = j;
        r.o[i] = (j == m ? 1ULL : 0ULL);
    }
    return r;
}

Seg power(Seg base, long long exp) {
    Seg ret = identity();
    while(exp > 0){
        if(exp & 1) ret = comp(ret, base);
        base = comp(base, base);
        exp >>= 1;
    }
    return ret;
}

string s;
int pos;

Seg parse() {
    Seg res = identity();
    while (pos < s.size() && s[pos] != ')'){
        Seg cur;
        if(isdigit(s[pos])){
            long long num = 0;
            while(pos < s.size() && isdigit(s[pos])){
                num = num * 10 + (s[pos] - '0');
                pos++;
            }
            if(pos < s.size() && s[pos] == '('){
                pos++;
                cur = parse();
                assert(pos < s.size() && s[pos] == ')');
                pos++;
            } else {
                cur = lit(s[pos]);
                pos++;
            }
            cur = power(cur, num);
        } else {
            cur = lit(s[pos]);
            pos++;
        }
        res = comp(res, cur);
    }
    return res;
}

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

    while(true){
        if(!getline(cin, s)) break;
        if(s == "#") break;
        getline(cin, q);

        buildAutomaton();
        pos = 0;
        Seg ans = parse();
        cout << ans.o[0] << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 1000
memory_kb: 5752
final_rank: 2

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
#define rep(i,n) for(ll i=0;i<n;i++)
#define all(A) A.begin(),A.end()


using pvl = pair<vll, vll>;
string Q;
ll QN;

pvl E() {
    pvl R;
    R.first.assign(QN + 1, 0);
    R.second.assign(QN + 1, 0);
    rep(i, QN + 1)R.first[i] = i;
    return R;
}
pvl merge(pvl A, pvl B) {
    pvl R;
    R.first.assign(QN + 1, 0);
    R.second.assign(QN + 1, 0);
    rep(i, QN + 1) {
        R.first[i] = B.first[A.first[i]];
        R.second[i] = B.second[A.first[i]] + A.second[i];
    }
    return R;
}
pvl prod(ll N, pvl A) {
    pvl R = E();
    while (N > 0) {
        if (N % 2 == 1)R = merge(R, A);
        N /= 2;
        A = merge(A, A);
    }
    return R;
}

vll PF(string S) {
    ll SN = S.size();
    vll res(SN);
    ll len = 0;
    for (ll i = 1; i < SN; ++i) {
        if (S[i] == S[len]) {
            ++len;
            res[i] = len;
        }
        else {
            if (len != 0) {
                len = res[len - 1];
                --i;
            }
            else {
                res[i] = 0;
            }
        }
    }
    return res;
}
vector<pvl> init(string S) {
    S.push_back('*');//dummy
    ll SN = S.size();
    auto LPS = PF(S);
    vector<pvl> R(26);
    rep(i, 26) {
        R[i].first.assign(SN, 0);
        R[i].second.assign(SN, 0);
    }
    rep(c, 26) {
        rep(i, SN) {
            if (S[i] - 'A' == c) {
                R[c].first[i] = i + 1;
                R[c].second[i] = 0;
            }
            else {
                R[c].first[i] = (i > 0 ? R[c].first[LPS[i - 1]] : 0);
                R[c].second[i] = 0;
            }
        }
        rep(i, SN)if (R[c].first[i] == SN - 1)R[c].second[i] = 1;
    }
    return R;
}


//半解説AC
void solve(string S) {
    cin >> Q;
    QN = Q.size();
    ll SN = S.size();
    string NS = "";
    rep(i, SN) {
        if (i < SN - 1 && '0' <= S[i] && S[i] <= '9' && 'A' <= S[i + 1] && S[i + 1] <= 'Z') {
            NS.push_back(S[i]);
            NS.push_back('(');
            NS.push_back(S[i + 1]);
            NS.push_back(')');
            i++;
        }
        else NS.push_back(S[i]);
    }
    swap(S, NS);
    SN = S.size();
    ll cnt = 0;
    vector<pvl> V(SN + 1, E());
    vll d(SN + 1, -1);
    auto BEG = init(Q);
    rep(i, SN) {
        if ('0' <= S[i] && S[i] <= '9') {
            if (d[cnt] < 0) {
                d[cnt] = S[i] - '0';
            }
            else {
                d[cnt] = 10 * d[cnt] + S[i] - '0';
            }
        }
        else if (S[i] == '(') {
            cnt++;
        }
        else if (S[i] == ')') {
            if (d[cnt - 1] > 0) {
                V[cnt] = prod(d[cnt - 1], V[cnt]);
            }
            V[cnt - 1] = merge(V[cnt - 1], V[cnt]);
            V[cnt] = E();
            d[cnt - 1] = -1;
            cnt--;
        }
        else {
            V[cnt] = merge(V[cnt], BEG[S[i] - 'A']);
        }
    }
    cout << V[0].second[0] << endl;

}

int main() {
    string S;
    while (cin >> S, S != "#")solve(S);
}
accuracy: 1
time_ms: 2600
memory_kb: 207696
final_rank: 20

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

template < class T > vector< T >& operator++(vector< T >& a) { for(T& x : a) x++; return a; }
template < class T > vector< T >& operator--(vector< T >& a) { for(T& x : a) x--; return a; }
template < class T > vector< T >  operator++(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x++; return res; }
template < class T > vector< T >  operator--(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x--; return res; }

} // namespace macro

using namespace macro;
#line 3 "cp-library/src/utility/random.hpp"

namespace randnum {

static uint seed;
static std::mt19937 mt;
struct gen_seed {
    gen_seed() {
        seed = std::random_device()();
        mt = std::mt19937(seed);
    }
} gs;

// [L, R)
template < class T >
T gen_int(T L, T R) {
    return std::uniform_int_distribution< T >(L, R - 1)(mt);
}

template < class T >
T get_real(T L, T R) {
    return std::uniform_real_distribution< T >(L, R)(mt);
}

}
#line 3 "cp-library/src/utility/hash.hpp"

template < int num_of_mod = 2 >
struct hash_vector : public array<ll, num_of_mod> {
    //static constexpr ll MODS[] = {999999937, 1000000007, 1000000009, 1000000021};
    static constexpr ll MODS[] = {1000000021, 999999937, 1000000007, 1000000009, };
    static_assert(1 <= num_of_mod and num_of_mod <= 4);
    using array<ll, num_of_mod>::operator[];
    using H = hash_vector;
    static constexpr int n = num_of_mod;
    hash_vector() : array<ll,n>() {}
    hash_vector(ll x) : H() { for(int i : rep(n)) (*this)[i] = x % MODS[i]; }
    H& operator+=(const H& rhs) { for(int i : rep(n)) if(((*this)[i] += rhs[i]) >= MODS[i]) (*this)[i] -= MODS[i]; return *this; }
    H& operator-=(const H& rhs) { for(int i : rep(n)) if(((*this)[i] += MODS[i] - rhs[i]) >= MODS[i]) (*this)[i] -= MODS[i]; return *this; }
    H& operator*=(const H& rhs) { for(int i : rep(n)) (*this)[i] = (*this)[i] * rhs[i] % MODS[i]; return *this; }
    H& operator+=(const ll rhs) { for(int i : rep(n)) if(((*this)[i] += rhs % MODS[i]) >= MODS[i]) (*this)[i] -= MODS[i]; return *this; }
    H& operator-=(const ll rhs) { for(int i : rep(n)) if(((*this)[i] += MODS[i] - rhs % MODS[i]) >= MODS[i]) (*this)[i] -= MODS[i]; return *this; }
    H& operator*=(const ll rhs) { for(int i : rep(n)) (*this)[i] = (*this)[i] * (rhs % MODS[i]) % MODS[i]; return *this; }
    H operator+(const H& rhs) const { return H(*this) += rhs; }
    H operator-(const H& rhs) const { return H(*this) -= rhs; }
    H operator*(const H& rhs) const { return H(*this) *= rhs; }
    H operator+(const ll rhs) const { return H(*this) += rhs; }
    H operator-(const ll rhs) const { return H(*this) -= rhs; }
    H operator*(const ll rhs) const { return H(*this) *= rhs; }
    H operator-() const { return H().fill(0) - *this; }
    friend H operator+(ll x, const H& y) { return H(x) + y; }
    friend H operator-(ll x, const H& y) { return H(x) + y; }
    friend H operator*(ll x, const H& y) { return H(x) * y; }
    bool operator==(const H& rhs) { for(int i : rep(n)) if((*this)[i] != rhs[i]) return false; return true ; }
    bool operator!=(const H& rhs) { for(int i : rep(n)) if((*this)[i] != rhs[i]) return true ; return false; }
};
#line 4 "cp-library/src/string/rolling_hash.hpp"


constexpr ll BASE = 10007;
template< int num_of_mod = 2 >
struct rolling_hash {

    static const ll BASE;

    vector< hash_vector< num_of_mod > > pb, hs;
    rolling_hash() {}
    rolling_hash(const string& s) {
        int n = s.size();
        hs.resize(n + 1); hs[0].fill(0);
        pb.resize(n + 1); pb[0].fill(1);
        for(int i : rep(n)) {
            hs[i + 1] = hs[i] * BASE + s[i];
            pb[i + 1] = pb[i] * BASE;
        }
    }

    // [l, r)
    hash_vector< num_of_mod > get(int l, int r) const {
        return hs[r] - hs[l] * pb[r - l];
    }

    hash_vector< num_of_mod > concat(hash_vector< num_of_mod > h1, hash_vector< num_of_mod > h2, int h2_len) {
        assert(0 <= h2_len and h2_len < int(pb.size()));
        return h1 * pb[h2_len] + h2;
    }

    template < int n >
    static int lcp(const rolling_hash< n >& rh1, int l1, int r1, const rolling_hash< n >& rh2, int l2, int r2) {
        int lo = -1, hi = min(r1 - l1, r2 - l2) + 1;
        while(hi - lo > 1) {
            int mid = (lo + hi) / 2;
            (rh1.get(l1, l1 + mid) == rh2.get(l2, l2 + mid) ? lo : hi) = mid;
        }
        return lo;
    }

    template < int n >
    static int cmp(const string& s1, const rolling_hash< n >& rh1, int l1, int r1,
                   const string& s2, const rolling_hash< n >& rh2, int l2, int r2) {
        int len = lcp(rh1, l1, r1, rh2, l2, r2);
        if(len == r1 - l1 && len == r2 - l2) return 0;
        if(len == r1 - l1) return -1;
        if(len == r2 - l2) return +1;
        return (s1[l1 + len] < s2[l2 + len] ? -1 : +1);
    }
};

template < int num_of_mod >
const ll rolling_hash< num_of_mod >::BASE = randnum::gen_int<ll>(ll(0), hash_vector< num_of_mod >::MODS[0]);
#line 4 "A.cpp"

string s, q;
int n, m;
rolling_hash<2> hq;
struct Data {
    i64 len, answer;
    string prefix, suffix;
    Data() {
        len = 0;
        answer = 0;
        prefix = "";
        suffix = "";
    }
};

Data merge(Data, Data);
Data power(Data, i64);
Data genome(int&);
Data letter(int&);
i64 number(int&);

i64 count(string x) {
    if(x.size() < m) return 0;
    i64 res = 0;
    rolling_hash<2> hx(x);
    for(int i : rep(int(x.size()) - m + 1)) res += (hx.get(i, i + m) == hq.get(0, m));
    return res;
}

Data merge(Data L, Data R) {
    Data res;
    if(L.len + R.len < m) {
        res.len = L.len + R.len;
        res.answer = L.answer + R.answer + count(L.prefix + R.prefix);
        res.prefix = L.prefix + R.prefix;
        res.suffix = L.suffix + R.suffix;
    } else {
        res.len = L.len + R.len;
        res.answer = L.answer + R.answer + count(L.suffix + R.prefix);
        res.prefix = (L.prefix + R.prefix).substr(0, m - 1);
        string x = L.suffix + R.suffix;
        reverse(x);
        x = x.substr(0, m - 1);
        reverse(x);
        res.suffix = x;
    }
    return res;
}

Data power(Data X, i64 n) {
    Data res;
    while(n) {
        if(n % 2 == 1) res = merge(res, X);
        X = merge(X, X);
        n /= 2;
    }
    return res;
}

Data genome(int& i) {
    Data res;
    while(i < n) {
        if(std::isalpha(s[i])) {
            Data c = letter(i);
            res = merge(res, c);
        } else if(std::isdigit(s[i])) {
            i64 num = number(i);
            if(std::isalpha(s[i])) {
                Data c = letter(i);
                res = merge(res, power(c, num));
            } else {
                assert(s[i] == '(');
                i++;
                Data g = genome(i);
                res = merge(res, power(g, num));
                assert(s[i] == ')');
                i++;
            }
        } else break;
    }
    return res;
}

Data letter(int& i) {
    char c = s[i]; i++;
    Data res;
    res.len = 1;
    if(m == 1) {
        res.answer = (q[0] == c);
    } else {
        res.prefix += c;
        res.suffix += c;
    }
    return res;
}

i64 number(int& i) {
    i64 res = 0;
    while(i < n and std::isdigit(s[i])) {
        res = res * 10 + (s[i] - '0');
        i++;
    }
    return res;
}

int main() {
    while(true) {
        cin >> s;
        if(s == "#") return 0;
        cin >> q;
        hq = rolling_hash<2>(q);
        n = s.size();
        m = q.size();
        int i = 0;
        Data res = genome(i);
        print(res.answer);
    }
}
accuracy: 1
time_ms: 2840
memory_kb: 3936
final_rank: 11

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

template < class T > vector< T >& operator++(vector< T >& a) { for(T& x : a) x++; return a; }
template < class T > vector< T >& operator--(vector< T >& a) { for(T& x : a) x--; return a; }
template < class T > vector< T >  operator++(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x++; return res; }
template < class T > vector< T >  operator--(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x--; return res; }

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

string s, q;
int n, m;
struct Data {
    i64 len, answer;
    string prefix, suffix;
    Data() {
        len = 0;
        answer = 0;
        prefix = "";
        suffix = "";
    }
};

Data merge(Data, Data);
Data power(Data, i64);
Data genome(int&);
Data letter(int&);
i64 number(int&);

i64 count(string x) {
    if(x.size() < m) return 0;
    i64 res = 0;
    for(int i : rep(int(x.size()) - m + 1)) res += (x.substr(i, m) == q);
    return res;
}

Data merge(Data L, Data R) {
    Data res;
    if(L.len + R.len < m) {
        res.len = L.len + R.len;
        res.answer = L.answer + R.answer + count(L.prefix + R.prefix);
        res.prefix = L.prefix + R.prefix;
        res.suffix = L.suffix + R.suffix;
    } else {
        res.len = L.len + R.len;
        res.answer = L.answer + R.answer + count(L.suffix + R.prefix);
        res.prefix = (L.prefix + R.prefix).substr(0, m - 1);
        string x = L.suffix + R.suffix;
        reverse(x);
        x = x.substr(0, m - 1);
        reverse(x);
        res.suffix = x;
    }
    return res;
}

Data power(Data X, i64 n) {
    Data res;
    while(n) {
        if(n % 2 == 1) res = merge(res, X);
        X = merge(X, X);
        n /= 2;
    }
    return res;
}

Data genome(int& i) {
    Data res;
    while(i < n) {
        if(std::isalpha(s[i])) {
            Data c = letter(i);
            res = merge(res, c);
        } else if(std::isdigit(s[i])) {
            i64 num = number(i);
            if(std::isalpha(s[i])) {
                Data c = letter(i);
                res = merge(res, power(c, num));
            } else {
                assert(s[i] == '(');
                i++;
                Data g = genome(i);
                res = merge(res, power(g, num));
                assert(s[i] == ')');
                i++;
            }
        } else break;
    }
    return res;
}

Data letter(int& i) {
    char c = s[i]; i++;
    Data res;
    res.len = 1;
    if(m == 1) {
        res.answer = (q[0] == c);
    } else {
        res.prefix += c;
        res.suffix += c;
    }
    return res;
}

i64 number(int& i) {
    i64 res = 0;
    while(i < n and std::isdigit(s[i])) {
        res = res * 10 + (s[i] - '0');
        i++;
    }
    return res;
}

int main() {
    while(true) {
        cin >> s;
        if(s == "#") return 0;
        cin >> q;
        n = s.size();
        m = q.size();
        int i = 0;
        Data res = genome(i);
        print(res.answer);
    }
}
accuracy: 1
time_ms: 6970
memory_kb: 3756
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, a, b) for (ll i = ll(a); i < ll(b); i++)
#define all(p) begin(p),end(p)

vector<ll> Z(string s){
    vector<ll> z(s.size(), s.size());
    ll l = -1, r = -1;
    rep(i, 1, s.size()){
        z[i] = i >= r ? 0 : min(r - i, z[i - l]);
        while (i + z[i] < s.size() && s[i + z[i]] == s[z[i]]) z[i]++;
        if (i + z[i] > r) l = i, r = i + z[i];
    }
    return z;
}

void solve(string S){
    string Q;
    cin >> Q;
    int D = 26;
    int N = S.size(), M = Q.size();
    auto z = Z(Q);
    using F = vector<pair<int, ll>>;
    vector<F> to(D);
    rep(i, 0, D) to[i].resize(M);
    rep(c, 0, D) rep(i, 0, M){
        pair<int, int> tmp;
        tmp.first = -1;
        tmp.second = 0;
        if (Q[i] == (char)(c + 'A')){
            tmp.first = i + 1;
            if (tmp.first == M){
                tmp.first = -1;
                tmp.second = 1;
            }
        }
        if (tmp.first == -1){
            tmp.first = 0;
            rep(j, 1, i + 1){
                if (z[j] >= i - j && Q[i - j] == (char)(c + 'A')){
                    tmp.first = i + 1 - j;
                    break;
                }
            }
        }
        to[c][i] = tmp;
    }
    auto merge = [&](F a, F b) -> F {
        F c(M);
        rep(i, 0, M){
            int d = a[i].first;
            c[i] = {b[d].first, b[d].second + a[i].second};
        }
        return c;
    };
    auto my_pow = [&](F a, ll times) -> F {
        times--;
        auto v = a;
        while (times){
            if (times & 1) v = merge(v, a);
            a = merge(a, a);
            times /= 2;
        }
        return v;
    };
    int ind = 0;
    auto f = [&](auto self) -> F {
        F res(M);
        for (int i = 0; i < M; i++) res[i] = {i, 0};
        ll X = -1;
        while (ind != N){
            if (S[ind] == ')'){
                ind++;
                break;
            }
            if ('0' <= S[ind] && S[ind] <= '9'){
                X = 0;
                while ('0' <= S[ind] && S[ind] <= '9'){
                    X *= 10;
                    X += S[ind] -'0';
                    ind++;
                }
            }
            else{
                if (X == -1){
                    X = 1;
                }
                if (S[ind] == '('){
                    ind++;
                    res = merge(res, (my_pow(self(self), X)));
                }
                else{
                    res = merge(res, my_pow(to[S[ind++] - 'A'], X));
                }
                X = -1;
            }
        }
        return res;
    };
    cout << (f(f))[0].second << "\n";
}

int main(){
    string S;
    while (cin >> S, S != "#") solve(S);
}
accuracy: 1
time_ms: 3320
memory_kb: 7168
final_rank: 14

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

using namespace std;
using i64 = long long;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;

int n, m;
string s, t;

struct Genome;

struct Genomes{
    vector<Genome*> v;
};

struct Genome{
    char letter = 0;
    i64 num = 0;
    Genomes* children = nullptr;
    int r = -1;
};

struct Result{
    i64 len = 0;
    string head = "";
    string tail = "";
    i64 occ = 0;
};



i64 match_matagi(string& a, string& b){
    // a と b を跨ぐような出現回数
    string c = a + b;
    i64 cnt = 0;
    for (int i = 0; i < a.size(); ++i) {
        if(a.size() < i + m && i + m <= c.size()){
            cnt += (c.substr(i, m) == t);
        }
    }
    return cnt;
}

i64 match(string& a){
    if(a.size() < m){
        return 0;
    }
    i64 cnt = 0;
    for (int i = 0; i < a.size() - m + 1; ++i) {
        cnt += (a.substr(i, m) == t);
    }
    return cnt;
}

Result merge(Result& a, Result& b){
    if(a.len + b.len <= m){
        Result r;
        r.len = a.len + b.len;
        r.head = r.tail = a.head + b.tail;
        r.occ = match(r.head);
        return r;
    }
    Result r;
    r.len = a.len + b.len;
    r.head = (a.head + b.head).substr(0, m);
    r.tail = (a.tail + b.tail).substr(max(0LL, i64((a.head + b.tail).length()) - m));
    assert(r.head.length() == m);
    assert(r.tail.length() == m);
    r.occ = a.occ + b.occ + match_matagi(a.tail, b.head);
    return r;
}

Genome* parse_genome(int l);

Genomes* parse_genomes(int l){
    vector<Genome*> v;
    while(s[l] != ')' && s[l] != '#'){
        Genome* g = parse_genome(l);
        l = g->r;
        v.emplace_back(g);
    }
    Genomes* g = new Genomes;
    g->v = move(v);
    return g;
}

Genome* parse_genome(int l){
    // letter
    if('A' <= s[l] && s[l] <= 'Z'){
        Genome* g = new Genome();
        g->letter = s[l];
        g->r = l + 1;
        return g;
    }
    // number
    if('0' <= s[l] && s[l] <= '9'){
        i64 num = s[l] - '0';
        ++l;
        // while(s[l] == '0'){
        while('0' <= s[l] && s[l] <= '9'){
            num *= 10;
            num += s[l] - '0';
            ++l;
        }
        // num letter
        if('A' <= s[l] && s[l] <= 'Z'){
            Genome* g = new Genome();
            g->num = num;
            Genomes* v = new Genomes();
            Genome* ch = new Genome();
            ch->letter = s[l];
            v->v.emplace_back(ch);
            g->children = v;
            g->r = l + 1;
            return g;
        }
        // num genome
        if(s[l] == '('){
            ++l;
            Genomes* children = parse_genomes(l);
            l = children->v.back()->r;
            assert(s[l] == ')');
            ++l;
            Genome* g = new Genome;
            g->num = num;
            g->children = children;
            g->r = l;
            return g;
        }
        assert(false);
    }
    assert(false);
}

Result rec(Genome* genome);

Result rec(Genomes* genomes){
    auto v = genomes->v;
    Result r = Result();
    for(auto g : v){
        Result rg = rec(g);
        r = merge(r, rg);
    }
    return r;
}

Result rec(Genome* genome){
    if(genome->letter != 0){
        // L
        Result r = Result();
        r.len = 1;
        r.occ = (string(1, genome->letter) == t);
        r.head += genome->letter;
        r.tail += genome->letter;
        return r;
    }
    i64 num = genome->num;
    Result x = Result();
    Result y = rec(genome->children);
    while(num){
        if(num & 1){
            x = merge(x, y);
        }
        num /= 2;
        y = merge(y, y);
        // cout << y.occ << endl;
    }
    // cout << "head tail: " << x.head << " " << x.tail << endl;
    // cout << "occ: " << x.occ << endl;
    return x;
}

bool solve(){
    cin >> s;
    if(s == "#"){
        return false;
    }
    cin >> t;
    n = s.size();
    m = t.size();
    s += '#';
    Genomes* g = parse_genomes(0);
    Result res = rec(g);
    // cout << res.head << endl;
    cout << res.occ << endl;
    return true;
}

int main() {
    while(solve());
    return 0;
}
accuracy: 1
time_ms: 6550
memory_kb: 7860
final_rank: 16

code_snippet: #include <string.h>

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cfloat>
#include <chrono>
#include <ciso646>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <optional>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#define REP_OVERLOAD(arg1, arg2, arg3, arg4, NAME, ...) NAME
#define REP3(i, l, r, s)                                               \
    for (int i = int(l), rep3_r = int(r), rep3_s = int(s); i < rep3_r; \
         i += rep3_s)
#define REP2(i, l, r) REP3(i, l, r, 1)
#define REP1(i, n) REP2(i, 0, n)
#define rep(...) REP_OVERLOAD(__VA_ARGS__, REP3, REP2, REP1, )(__VA_ARGS__)
#define repin(i, l, r) for (int i = int(l), repin_r = int(r); i <= repin_r; ++i)

#define RREP_OVERLOAD(arg1, arg2, arg3, arg4, NAME, ...) NAME
#define RREP3(i, l, r, s)                                                      \
    for (int i = int(r) - 1, rrep3_l = int(l), rrep3_s = int(s); i >= rrep3_l; \
         i -= rrep3_s)
#define RREP2(i, l, r) RREP3(i, l, r, 1)
#define RREP1(i, n) RREP2(i, 0, n)
#define rrep(...) RREP_OVERLOAD(__VA_ARGS__, RREP3, RREP2, RREP1, )(__VA_ARGS__)
#define rrepin(i, l, r) \
    for (int i = int(r), rrepin_l = int(l); i >= rrepin_l; --i)


#include <algorithm>
#include <cassert>
#include <vector>

namespace rklib {

// a <- max(a, b)
template <class T>
bool chmax(T &a, const T &b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

// a <- min(a, b)
template <class T>
bool chmin(T &a, const T &b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}

// if a < 0: a <- b
// else: a <- min(a, b)
template <class T>
bool chmin_non_negative(T &a, const T &b) {
    if (a < 0 || a > b) {
        a = b;
        return true;
    }
    return false;
}

// floor(num / den)
template <class T>
T div_floor(T num, T den) {
    if (den < 0) num = -num, den = -den;
    return num >= 0 ? num / den : (num + 1) / den - 1;
}

// ceil(num / den)
template <class T>
T div_ceil(T num, T den) {
    if (den < 0) num = -num, den = -den;
    return num <= 0 ? num / den : (num - 1) / den + 1;
}

namespace internal {

template <class T>
T remainder_count(T r, T b, T m) {
    return r / m * b + std::min(b, r % m);
}

}  // namespace internal

// Number of integer x s.t.
// - x in [l, r)
// - x mod m in [a, b)
template <class T>
T remainder_count(T l, T r, T a, T b, T m) {
    assert(l >= 0);
    assert(m >= 1);

    if (l >= r || a >= b) return 0;
    if (m <= a || b < 0) return 0;
    chmax(a, T(0));
    chmin(b, m);

    auto res = internal::remainder_count(r, b, m);
    if (l >= 1) res -= internal::remainder_count(l, b, m);
    if (a >= 1) res -= internal::remainder_count(r, a, m);
    if (l >= 1 && a >= 1) res += internal::remainder_count(l, a, m);

    return res;
}

}  // namespace rklib


using namespace std;
using namespace rklib;

using lint = long long;
using pii = pair<int, int>;
using pll = pair<lint, lint>;

template <class T>
struct KMP {
    T p;
    vector<int> fail;

    KMP(T p) : p(p) {
        fail.resize(p.size() + 1);
        fail[0] = -1;
        for (int i = -1, j = 0; j < (int)p.size();) {
            while (i >= 0 && p[i] != p[j]) i = fail[i];
            ++i;
            ++j;
            fail[j] = i;
        }
    }

    int next_state(int state, int c) {
        if (state == int(p.size())) {
            state = fail[state];
        }
        while (state >= 0 && p[state] != c) state = fail[state];
        ++state;
        return state;
    }
};

vector<vector<int>> nxt_one;
vector<vector<lint>> num_one;

bool is_alphabet(char c) { return 'A' <= c && c <= 'Z'; }

string s, t;
int idx;

pair<vector<int>, vector<lint>> expr();
pair<vector<int>, vector<lint>> term();
lint number();

pair<vector<int>, vector<lint>> merge(pair<vector<int>, vector<lint>> &a,
                                      pair<vector<int>, vector<lint>> &b) {
    auto nxt = a.first;
    auto num = a.second;
    rep(c, nxt.size()) {
        nxt[c] = a.first[b.first[c]];
        num[c] = b.second[c] + a.second[b.first[c]];
    }

    return {nxt, num};
}

pair<vector<int>, vector<lint>> expr() {
    auto [nxt_res, num_res] = term();
    while (idx < int(s.size()) && s[idx] != ')') {
        auto [nxt, num] = term();
        auto p = make_pair(nxt_res, num_res);
        auto q = make_pair(nxt, num);
        auto [a, b] = merge(q, p);
        nxt_res = a;
        num_res = b;
    }
    return {nxt_res, num_res};
}
pair<vector<int>, vector<lint>> term() {
    if (isdigit(s[idx])) {
        auto coef = number();
        ++idx;
        auto [nxt, num] = expr();
        ++idx;

        vector<int> nxt_res(nxt.size());
        iota(nxt_res.begin(), nxt_res.end(), 0);
        vector<lint> num_res(num.size(), 0);
        while (coef) {
            if (coef & 1) {
                auto p = make_pair(nxt_res, num_res);
                auto q = make_pair(nxt, num);
                auto [a, b] = merge(q, p);
                nxt_res = a;
                num_res = b;
                coef -= 1;
            } else {
                auto p = make_pair(nxt, num);
                auto [a, b] = merge(p, p);
                nxt = a;
                num = b;
                coef >>= 1;
            }
        }
        return {nxt_res, num_res};
    } else {
        ++idx;
        return {nxt_one[s[idx - 1] - 'A'], num_one[s[idx - 1] - 'A']};
    }
}
lint number() {
    lint res = 0;
    while (isdigit(s[idx])) {
        res = res * 10 + (s[idx] - '0');
        ++idx;
    }
    return res;
}

int main() {
    while (true) {
        cin >> s;
        if (s == "#") break;
        cin >> t;

        int n = s.size(), m = t.size();

        {
            string u;
            for (int i = 0; i < n;) {
                if (i < n - 1 && isdigit(s[i]) && is_alphabet(s[i + 1])) {
                    u += s[i];
                    u += '(';
                    u += s[i + 1];
                    u += ')';
                    i += 2;
                } else {
                    u += s[i];
                    ++i;
                }
            }
            s = u;
        }

        auto kmp = KMP(t);
        nxt_one.clear();
        num_one.clear();
        nxt_one.resize(26);
        num_one.resize(26);
        rep(c, 26) {
            nxt_one[c].resize(m + 1, 0);
            num_one[c].resize(m + 1, 0);
            rep(i, m + 1) {
                nxt_one[c][i] = kmp.next_state(i, c + 'A');
                if (nxt_one[c][i] == m) {
                    num_one[c][i] = 1;
                }
            }
        }

        idx = 0;
        auto [nxt, num] = expr();
        cout << num[0] << "\n";
    }
}
accuracy: 1
time_ms: 3390
memory_kb: 6232
final_rank: 15

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

#define rep(i, s, n) for (int i = (int)(s); i < (int)(n); i++)
#define rrep(i, s, n) for (int i = (int)(n)-1; i >= (int)(s); i--)
#define all(v) v.begin(), v.end()

using ll = long long;
using ld = long double;
using ull = unsigned long long;

template <typename T> bool chmin(T &a, const T &b) {
    if (a <= b) return false;
    a = b;
    return true;
}
template <typename T> bool chmax(T &a, const T &b) {
    if (a >= b) return false;
    a = b;
    return true;
}

typedef std::string::const_iterator State;

bool expect(State &begin, char expected) {
    return *begin == expected;
}

void consume(State &begin, char expected) {
    if (*begin == expected)
        begin++;
    else
        assert(0);
}

bool isdigit(char c) {
    return '0' <= c && c <= '9';
}

bool isAlpha(char c) {
    return 'A' <= c && c <= 'Z';
}

std::vector<int> Z_Algorithm(const std::string &s) {
    int n = s.size();
    std::vector<int> prefix(n);
    prefix[0] = n;
    int i = 1;
    int j = 0;

    while (i < n) {
        while (i + j < n && s[j] == s[i + j]) ++j;
        prefix[i] = j;
        if (j == 0) {
            ++i;
            continue;
        }
        int k = 1;
        while (i + k < n && k + prefix[k] < j) {
            prefix[i + k] = prefix[k];
            ++k;
        }
        i += k;
        j -= k;
    }
    return prefix;
}

using bitset = std::bitset<3001>;

std::string q;

struct Node {
    ll n;
    ll sum = 0;
    std::string s = "";
    bitset prefix, suffix;
};

Node merge(const Node &lhs, const Node &rhs) {
    Node node;
    node.n = lhs.n + rhs.n;
    node.sum = lhs.sum + rhs.sum;
    node.suffix = lhs.suffix;
    node.prefix = rhs.prefix;
    rep(i, 1, q.size()) {
        node.sum += ll(lhs.prefix[i] && rhs.suffix[i]);
    }
    if (lhs.n < (int)q.size()) {
        auto z = Z_Algorithm(lhs.s + q);
        rep(i, lhs.n + 1, q.size()) {
            if (z[i] >= lhs.n) {
                if (i < (int)q.size() && rhs.suffix[i]) {
                    node.suffix[i - lhs.n] = 1;
                }
            }
        }
    }
    if (rhs.n < (int)q.size()) {
        auto z = Z_Algorithm(rhs.s + q);
        rep(i, rhs.n, q.size()) {
            if (z[i] >= rhs.n) {
                if (i < (int)q.size() && lhs.prefix[i - rhs.n]) {
                    node.prefix[i] = 1;
                }
            }
        }
    }
    if (node.n < (int)q.size()) {
        node.s = lhs.s + rhs.s;
    }
    return node;
}

Node Genome(State &begin);
Node Letter(State &begin);
ll number(State &begin);

Node pow_node(Node x, ll n) {
    assert(n > 0);
    bool is_ok = false;
    Node ret;
    while (n > 0) {
        if (n & 1) {
            if (is_ok) {
                ret = merge(ret, x);
            } else {
                ret = x;
                is_ok = true;
            }
        }
        x = merge(x, x);
        n >>= 1;
    }
    return ret;
}

Node Genome(State &begin) {
    ll x = 1;
    Node node;
    if (isdigit(*begin)) {
        x = number(begin);
        if (expect(begin, '(')) {
            consume(begin, '(');
            node = Genome(begin);
            consume(begin, ')');
        } else {
            node = Letter(begin);
        }
        node = pow_node(node, x);
    } else {
        node = Letter(begin);
    }
    if (!expect(begin, ';') && !expect(begin, ')')) {
        node = merge(node, Genome(begin));
    }
    return node;
}

Node Letter(State &begin) {
    assert(isAlpha(*begin));
    Node node;
    node.n = 1;
    node.s += char(*begin);
    if (node.s == q) {
        node.sum = 1;
        consume(begin, *begin);
        return node;
    }
    if (q[0] == *begin) {
        node.prefix[1] = 1;
    }
    if (q.back() == *begin) {
        node.suffix[q.size() - 1] = 1;
    }
    consume(begin, *begin);
    return node;
}

ll number(State &begin) {
    assert(isdigit(*begin));
    ll x = 0;
    while (isdigit(*begin)) {
        x *= 10;
        x += *begin - '0';
        consume(begin, *begin);
    }
    return x;
}

int main() {
    std::string s;
    while (std::cin >> s, !(s == "#")) {
        std::cin >> q;
        s += ';';
        State begin = s.begin();
        Node ans = Genome(begin);
        consume(begin, ';');
        std::cout << ans.sum << '\n';
    }
}
accuracy: 1
time_ms: 2070
memory_kb: 15520
final_rank: 9

code_snippet: #include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <memory>
#include <numeric>
#include <optional>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

/* macro */

#define rep(i, a, n) for (int i = (int)(a); i < (int)(n); i++)
#define rrep(i, a, n) for (int i = ((int)(n)-1); i >= (int)(a); i--)
#define Rep(i, a, n) for (i64 i = (i64)(a); i < (i64)(n); i++)
#define RRep(i, a, n) for (i64 i = ((i64)(n)-i64(1)); i >= (i64)(a); i--)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()

/* macro end */

/* template */

namespace ebi {

#ifdef LOCAL
#define debug(...)                                                      \
    std::cerr << "LINE: " << __LINE__ << "  [" << #__VA_ARGS__ << "]:", \
        debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif

void debug_out() {
    std::cerr << std::endl;
}

template <typename Head, typename... Tail> void debug_out(Head h, Tail... t) {
    std::cerr << " " << h;
    if (sizeof...(t) > 0) std::cout << " :";
    debug_out(t...);
}

template <typename T1, typename T2>
std::ostream &operator<<(std::ostream &os, const std::pair<T1, T2> &pa) {
    return os << pa.first << " " << pa.second;
}

template <typename T1, typename T2>
std::istream &operator>>(std::istream &os, std::pair<T1, T2> &pa) {
    return os >> pa.first >> pa.second;
}

template <typename T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &vec) {
    for (std::size_t i = 0; i < vec.size(); i++)
        os << vec[i] << (i + 1 == vec.size() ? "" : " ");
    return os;
}

template <typename T>
std::istream &operator>>(std::istream &os, std::vector<T> &vec) {
    for (T &e : vec) std::cin >> e;
    return os;
}

template <typename T>
std::ostream &operator<<(std::ostream &os, const std::optional<T> &opt) {
    if (opt) {
        os << opt.value();
    } else {
        os << "invalid value";
    }
    return os;
}

using std::size_t;
using i32 = std::int32_t;
using u32 = std::uint32_t;
using i64 = std::int64_t;
using u64 = std::uint64_t;

template <class T, T init> auto make_vector(int n) {
    return std::vector<T>(n, init);
}

template <class T, T init, typename Head, typename... Tail>
auto make_vector(Head n, Tail... ts) {
    return std::vector(n, make_vector<T, init>(ts...));
}

template <class T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}

template <class T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

template <class T> T pow(T x, i64 n) {
    T res = 1;
    while (n > 0) {
        if (n & 1) res = res * x;
        x = x * x;
        n >>= 1;
    }
    return res;
}

template <class T> T mod_pow(T x, i64 n, i64 mod) {
    T res = 1;
    while (n > 0) {
        if (n & 1) res = (res * x) % mod;
        x = (x * x) % mod;
        n >>= 1;
    }
    return res;
}

template <class T> T scan() {
    T val;
    std::cin >> val;
    return val;
}

template <class T> struct Edge {
    int to;
    T cost;
    Edge(int _to, T _cost = 1) : to(_to), cost(_cost) {}
};

template <class T> struct Graph : std::vector<std::vector<Edge<T>>> {
    using std::vector<std::vector<Edge<T>>>::vector;
    void add_edge(int u, int v, T w, bool directed = false) {
        (*this)[u].emplace_back(v, w);
        if (directed) return;
        (*this)[v].emplace_back(u, w);
    }
};

struct graph : std::vector<std::vector<int>> {
    using std::vector<std::vector<int>>::vector;
    void add_edge(int u, int v, bool directed = false) {
        (*this)[u].emplace_back(v);
        if (directed) return;
        (*this)[v].emplace_back(u);
    }
};

constexpr i64 LNF = std::numeric_limits<i64>::max() / 4;

constexpr int INF = std::numeric_limits<int>::max() / 2;

const std::vector<int> dy = {1, 0, -1, 0, 1, 1, -1, -1};
const std::vector<int> dx = {0, 1, 0, -1, 1, -1, 1, -1};

}  // namespace ebi

namespace ebi {

std::vector<int> Z_Algorithm(const std::string &s) {
    int n = s.size();
    std::vector<int> prefix(n);
    prefix[0] = n;
    int i = 1;
    int j = 0;

    while (i < n) {
        while (i + j < n && s[j] == s[i + j]) ++j;
        prefix[i] = j;
        if (j == 0) {
            ++i;
            continue;
        }
        int k = 1;
        while (i + k < n && k + prefix[k] < j) {
            prefix[i + k] = prefix[k];
            ++k;
        }
        i += k;
        j -= k;
    }
    return prefix;
}

}  // namespace ebi

namespace ebi {

typedef std::string::const_iterator State;

bool expect(State &begin, char expected) {
    return *begin == expected;
}

void consume(State &begin, char expected) {
    if (*begin == expected)
        begin++;
    else
        assert(0);
}

bool isdigit(char c) {
    return '0' <= c && c <= '9';
}

bool isAlpha(char c) {
    return 'A' <= c && c <= 'Z';
}

using bitset = std::bitset<3001>;

std::string q;

struct Node {
    i64 n;
    i64 sum = 0;
    std::string s = "";
    bitset prefix, suffix;
};

Node merge(const Node &lhs, const Node &rhs) {
    Node node;
    node.n = lhs.n + rhs.n;
    node.sum = lhs.sum + rhs.sum;
    node.suffix = lhs.suffix;
    node.prefix = rhs.prefix;
    rep(i, 1, q.size()) {
        node.sum += i64(lhs.prefix[i] && rhs.suffix[i]);
    }
    if (lhs.n < (int)q.size()) {
        auto z = Z_Algorithm(lhs.s + q);
        rep(i, lhs.n + 1, q.size()) {
            if (z[i] >= lhs.n) {
                if (i < (int)q.size() && rhs.suffix[i]) {
                    node.suffix[i - lhs.n] = 1;
                }
            }
        }
    }
    if (rhs.n < (int)q.size()) {
        auto z = Z_Algorithm(rhs.s + q);
        rep(i, rhs.n, q.size()) {
            if (z[i] >= rhs.n) {
                if (i < (int)q.size() && lhs.prefix[i - rhs.n]) {
                    node.prefix[i] = 1;
                }
            }
        }
    }
    if (node.n < (int)q.size()) {
        node.s = lhs.s + rhs.s;
    }
    return node;
}

Node Genome(State &begin);
Node Letter(State &begin);
i64 number(State &begin);

Node pow_node(Node x, i64 n) {
    assert(n > 0);
    bool is_ok = false;
    Node ret;
    while (n > 0) {
        if (n & 1) {
            if (is_ok) {
                ret = merge(ret, x);
            } else {
                ret = x;
                is_ok = true;
            }
        }
        x = merge(x, x);
        n >>= 1;
    }
    return ret;
}

Node Genome(State &begin) {
    i64 x = 1;
    Node node;
    if (isdigit(*begin)) {
        x = number(begin);
        if (expect(begin, '(')) {
            consume(begin, '(');
            node = Genome(begin);
            consume(begin, ')');
        } else {
            node = Letter(begin);
        }
        node = pow_node(node, x);
    } else {
        node = Letter(begin);
    }
    if (!expect(begin, ';') && !expect(begin, ')')) {
        node = merge(node, Genome(begin));
    }
    return node;
}

Node Letter(State &begin) {
    assert(isAlpha(*begin));
    Node node;
    node.n = 1;
    node.s += char(*begin);
    if (node.s == q) {
        node.sum = 1;
        consume(begin, *begin);
        return node;
    }
    if (q[0] == *begin) {
        node.prefix[1] = 1;
    }
    if (q.back() == *begin) {
        node.suffix[q.size() - 1] = 1;
    }
    consume(begin, *begin);
    return node;
}

i64 number(State &begin) {
    assert(isdigit(*begin));
    i64 x = 0;
    while (isdigit(*begin)) {
        x *= 10;
        x += *begin - '0';
        consume(begin, *begin);
    }
    return x;
}

void main_() {
    std::string s;
    while (std::cin >> s, !(s == "#")) {
        std::cin >> q;
        s += ';';
        State begin = s.begin();
        Node ans = Genome(begin);
        consume(begin, ';');
        std::cout << ans.sum << '\n';
    }
}

}  // namespace ebi

int main() {
    std::cout << std::fixed << std::setprecision(15);
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);
    int t = 1;
    // std::cin >> t;
    while (t--) {
        ebi::main_();
    }
    return 0;
}
accuracy: 1
time_ms: 2170
memory_kb: 15644
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T> bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; }
template <typename T> bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; }

template <typename T, typename U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    for (int i = 0; i < (int) v.size(); ++i) os << v[i] << " ";
    return os;
}

std::vector<int> prefix_function(const std::string& s) {
    const int n = s.size();
    std::vector<int> ret(n);
    int len = 0;
    for (int i = 1; i < n; ++i) {
        if (s[i] == s[len]) {
            ++len;
            ret[i] = len;
        } else {
            if (len != 0) {
                len = ret[len - 1];
                --i;
            } else {
                ret[i] = 0;
            }
        }
    }
    return ret;
}

template <int AlphabetSize, int Offset>
std::vector<std::vector<std::pair<int, bool>>> matching_automaton(const std::string& s) {
    const int n = s.size();
    auto lps = prefix_function(s);
    std::vector<std::vector<std::pair<int, bool>>> aut(n, std::vector<std::pair<int, bool>>(AlphabetSize));
    for (int i = 0; i < n; ++i) {
        for (int c = 0; c < AlphabetSize; ++c) {
            if (Offset + c == s[i]) {
                if (i == n - 1) aut[i][c] = {lps[i], true};
                else aut[i][c] = {i + 1, false};
            } else {
                aut[i][c] = {i > 0 ? aut[lps[i - 1]][c].first : 0, 0};
            }
        }
    }
    return aut;
}



int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    while (true) {
        string s;
        cin >> s;
        if (s == "#") break;
        string q;
        cin >> q;
        const int n = q.size();

        auto transition = matching_automaton<26, 'A'>(q);

        auto merge = [&](auto& a, auto& b) {
            vector<pair<int, ll>> c(n);
            rep(i,0,n) {
                auto [j1, m1] = a[i];
                auto [j2, m2] = b[j1];
                c[i] = {j2, m1+m2};
            }
            return c;
        };

        int k = 0;
        auto dfs = [&](auto& dfs) -> vector<pair<int, ll>> {
            vector<pair<int, ll>> nxt(n);
            rep(i,0,n) nxt[i] = {i, 0};
            while (k < s.size() && s[k] != ')') {
                ll m = 1;
                if ('0' <= s[k] && s[k] <= '9') {
                    string num = "";
                    while (k < s.size() && '0' <= s[k] && s[k] <= '9') num += s[k++];
                    m = stoll(num);
                }
                vector<pair<int, ll>> res(n), doubling(n);
                rep(i,0,n) res[i] = {i, 0};
                if (s[k] == '(') {
                    ++k;
                    doubling = dfs(dfs);
                    assert(s[k] == ')');
                    ++k;
                } else {
                    char c = s[k++] - 'A';
                    rep(i,0,n) doubling[i] = transition[i][c];
                }
                while (m) {
                    if (m & 1) {
                        res = merge(res, doubling);
                    }
                    doubling = merge(doubling, doubling);
                    m >>= 1;
                }
                nxt = merge(nxt, res);
            }
            return nxt;
        };

        auto ans = dfs(dfs);
        cout << ans[0].second << endl;
    }
}
accuracy: 1
time_ms: 1500
memory_kb: 11568
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T> bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; }
template <typename T> bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; }

template <typename T, typename U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    for (int i = 0; i < (int) v.size(); ++i) os << v[i] << " ";
    return os;
}

std::vector<int> prefix_function(const std::string& s) {
    const int n = s.size();
    std::vector<int> ret(n);
    int len = 0;
    for (int i = 1; i < n; ++i) {
        if (s[i] == s[len]) {
            ++len;
            ret[i] = len;
        } else {
            if (len != 0) {
                len = ret[len - 1];
                --i;
            } else {
                ret[i] = 0;
            }
        }
    }
    return ret;
}


int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    while (true) {
        string s;
        cin >> s;
        if (s == "#") break;
        string q;
        cin >> q;
        const int n = q.size();

        auto pf = prefix_function(q);
        vector<vector<pair<int, int>>> transition(n, vector<pair<int, int>>(26));
        rep(i,0,n) {
            rep(c,0,26) {
                if (c == q[i]-'A') {
                    if (i == n-1) {
                        transition[i][c] = {pf[i], 1};
                    } else {
                        transition[i][c] = {i+1, 0};
                    }
                } else if (i > 0) {
                    transition[i][c] = transition[pf[i-1]][c];
                }
            }
            // cout << transition[i] << endl;
        }

        auto merge = [&](auto& a, auto& b) {
            vector<pair<int, ll>> c(n);
            rep(i,0,n) {
                auto [j1, m1] = a[i];
                auto [j2, m2] = b[j1];
                c[i] = {j2, m1+m2};
            }
            return c;
        };

        int k = 0;
        auto dfs = [&](auto& dfs) -> vector<pair<int, ll>> {
            vector<pair<int, ll>> nxt(n);
            rep(i,0,n) nxt[i] = {i, 0};
            while (k < s.size() && s[k] != ')') {
                ll m = 1;
                if ('0' <= s[k] && s[k] <= '9') {
                    string num = "";
                    while (k < s.size() && '0' <= s[k] && s[k] <= '9') num += s[k++];
                    m = stoll(num);
                }
                vector<pair<int, ll>> res(n), doubling(n);
                rep(i,0,n) res[i] = {i, 0};
                if (s[k] == '(') {
                    ++k;
                    doubling = dfs(dfs);
                    assert(s[k] == ')');
                    ++k;
                } else {
                    char c = s[k++] - 'A';
                    rep(i,0,n) doubling[i] = transition[i][c];
                }
                while (m) {
                    if (m & 1) {
                        res = merge(res, doubling);
                    }
                    doubling = merge(doubling, doubling);
                    m >>= 1;
                }
                nxt = merge(nxt, res);
            }
            return nxt;
        };

        auto ans = dfs(dfs);
        cout << ans[0].second << endl;
    }
}
accuracy: 1
time_ms: 1490
memory_kb: 11532
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T> bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; }
template <typename T> bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; }

template <typename T, typename U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    for (int i = 0; i < (int) v.size(); ++i) os << v[i] << " ";
    return os;
}
template< int char_size >
struct TrieNode {
  int nxt[char_size];

  int exist;
  vector< int > accept;

  TrieNode() : exist(0) {
    memset(nxt, -1, sizeof(nxt));
  }
};

template< int char_size, int margin >
struct Trie {
  using Node = TrieNode< char_size >;

  vector< Node > nodes;
  int root;

  Trie() : root(0) {
    nodes.push_back(Node());
  }

  void update_direct(int node, int id) {
    nodes[node].accept.push_back(id);
  }

  void update_child(int node, int child, int id) {
    ++nodes[node].exist;
  }

  void add(const string &str, int str_index, int node_index, int id) {
    if(str_index == str.size()) {
      update_direct(node_index, id);
    } else {
      const int c = str[str_index] - margin;
      if(nodes[node_index].nxt[c] == -1) {
        nodes[node_index].nxt[c] = (int) nodes.size();
        nodes.push_back(Node());
      }
      add(str, str_index + 1, nodes[node_index].nxt[c], id);
      update_child(node_index, nodes[node_index].nxt[c], id);
    }
  }

  void add(const string &str, int id) {
    add(str, 0, 0, id);
  }

  void add(const string &str) {
    add(str, nodes[0].exist);
  }

  void query(const string &str, const function< void(int) > &f, int str_index, int node_index) {
    for(auto &idx : nodes[node_index].accept) f(idx);
    if(str_index == str.size()) {
      return;
    } else {
      const int c = str[str_index] - margin;
      if(nodes[node_index].nxt[c] == -1) return;
      query(str, f, str_index + 1, nodes[node_index].nxt[c]);
    }
  }

  void query(const string &str, const function< void(int) > &f) {
    query(str, f, 0, 0);
  }

  int count() const {
    return (nodes[0].exist);
  }

  int size() const {
    return ((int) nodes.size());
  }
};

template< int char_size, int margin >
struct AhoCorasick : Trie< char_size + 1, margin > {
  using Trie< char_size + 1, margin >::Trie;

  const int FAIL = char_size;
  vector< int > correct;

  void build(bool heavy = true) {
    correct.resize(this->size());
    for(int i = 0; i < this->size(); i++) {
      correct[i] = (int) this->nodes[i].accept.size();
    }
    queue< int > que;
    for(int i = 0; i <= char_size; i++) {
      if(~this->nodes[0].nxt[i]) {
        this->nodes[this->nodes[0].nxt[i]].nxt[FAIL] = 0;
        que.emplace(this->nodes[0].nxt[i]);
      } else {
        this->nodes[0].nxt[i] = 0;
      }
    }
    while(!que.empty()) {
      auto &now = this->nodes[que.front()];
      int fail = now.nxt[FAIL];
      correct[que.front()] += correct[fail];
      que.pop();
      for(int i = 0; i < char_size; i++) {
        if(~now.nxt[i]) {
          this->nodes[now.nxt[i]].nxt[FAIL] = this->nodes[fail].nxt[i];
          if(heavy) {
            auto &u = this->nodes[now.nxt[i]].accept;
            auto &v = this->nodes[this->nodes[fail].nxt[i]].accept;
            vector< int > accept;
            set_union(begin(u), end(u), begin(v), end(v), back_inserter(accept));
            u = accept;
          }
          que.emplace(now.nxt[i]);
        } else {
          now.nxt[i] = this->nodes[fail].nxt[i];
        }
      }
    }
  }

  map< int, int > match(const string &str, int now = 0) {
    map< int, int > result;
    for(auto &c : str) {
      now = this->nodes[now].nxt[c - margin];
      for(auto &v : this->nodes[now].accept) result[v] += 1;
    }
    return result;
  }

  pair< int64_t, int > move(const char &c, int now = 0) {
    now = this->nodes[now].nxt[c - margin];
    return {correct[now], now};
  }

  pair< int64_t, int > move(const string &str, int now = 0) {
    int64_t sum = 0;
    for(auto &c : str) {
      auto nxt = move(c, now);
      sum += nxt.first;
      now = nxt.second;
    }
    return {sum, now};
  }
};

std::vector<int> prefix_function(const std::string& s) {
    const int n = s.size();
    std::vector<int> ret(n);
    int len = 0;
    for (int i = 1; i < n; ++i) {
        if (s[i] == s[len]) {
            ++len;
            ret[i] = len;
        } else {
            if (len != 0) {
                len = ret[len - 1];
                --i;
            } else {
                ret[i] = 0;
            }
        }
    }
    return ret;
}


int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    while (true) {
        string s;
        cin >> s;
        if (s == "#") break;
        string q;
        cin >> q;
        const int n = q.size();

        AhoCorasick<26, 'A'> aho;
        aho.add(q);
        aho.build();
        auto pf = prefix_function(q);
        vector<vector<pair<int, int>>> transition(n, vector<pair<int, int>>(26));
        rep(i,0,n) {
            rep(c,0,26) {
                auto [m, j] = aho.move('A' + c, i);
                if (m == 1) j = pf[i];
                transition[i][c] = {j, m};
            }
        }

        auto merge = [&](auto& a, auto& b) {
            vector<pair<int, ll>> c(n);
            rep(i,0,n) {
                auto [j1, m1] = a[i];
                auto [j2, m2] = b[j1];
                c[i] = {j2, m1+m2};
            }
            return c;
        };

        int k = 0;
        auto dfs = [&](auto& dfs) -> vector<pair<int, ll>> {
            vector<pair<int, ll>> nxt(n);
            rep(i,0,n) nxt[i] = {i, 0};
            while (k < s.size() && s[k] != ')') {
                ll m = 1;
                if ('0' <= s[k] && s[k] <= '9') {
                    string num = "";
                    while (k < s.size() && '0' <= s[k] && s[k] <= '9') num += s[k++];
                    m = stoll(num);
                }
                vector<pair<int, ll>> res(n), doubling(n);
                rep(i,0,n) res[i] = {i, 0};
                if (s[k] == '(') {
                    ++k;
                    doubling = dfs(dfs);
                    assert(s[k] == ')');
                    ++k;
                } else {
                    char c = s[k++] - 'A';
                    rep(i,0,n) doubling[i] = transition[i][c];
                }
                while (m) {
                    if (m & 1) {
                        res = merge(res, doubling);
                    }
                    doubling = merge(doubling, doubling);
                    m >>= 1;
                }
                nxt = merge(nxt, res);
            }
            return nxt;
        };

        auto ans = dfs(dfs);
        cout << ans[0].second << endl;
    }
}
accuracy: 1
time_ms: 1340
memory_kb: 12412
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using ll = long long;
#define var auto
const char newl = '\n';

using namespace std;

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; }

ll count_occurence(string& s, string& target) {
  ll cnt = 0;
  for (int i = target.size(); i <= s.size(); i++) {
    if (s.substr(i - target.size(), target.size()) == target) cnt++;
  }
  return cnt;
}

string substr_from_end(string& s, ll len) {
  return s.substr(s.size() - len);
}


string Target;
struct Data {
  bool has_after;
  string prev;
  string after;
  ll cnt;

  Data(string& prev, string& after, ll cnt) : has_after(true), prev(prev), after(after), cnt(cnt) {}
  Data(string& s) : has_after(false), prev(s), after(), cnt(0) {}

  Data operator+(Data& a) {
    ll new_cnt = cnt + a.cnt;
    if (!has_after) {
      var new_prev = prev + a.prev;
      new_cnt += count_occurence(new_prev, Target);
      if (a.has_after) {
        assert(Target.size() - 1 <= new_prev.size());
        var p = new_prev.substr(0, Target.size() - 1);
        return Data(p, a.after, new_cnt);
      }
      else {
        if (Target.size() <= new_prev.size()) {
          var p = new_prev.substr(0, Target.size() - 1);
          var a = substr_from_end(new_prev, Target.size() - 1);
          return Data(p, a, new_cnt);
        }
        else {
          return Data(new_prev);
        }
      }
    }
    else {
      string middle = after + a.prev;
      new_cnt += count_occurence(middle, Target);
      if (a.has_after) {
        return Data(prev, a.after, new_cnt);
      }
      else {
        assert(Target.size() - 1 <= middle.size());
        var a = substr_from_end(middle, Target.size() - 1);
        return Data(prev, a, new_cnt);
      }
    }
    assert(false);
  }
  // kasu
  Data operator*(ll cnt) {
    string empty{};
    Data res(empty), tmp(*this);
    while (cnt) {
      if (cnt & 1) res = res + tmp;
      tmp = tmp + tmp;
      cnt >>= 1;
    }
    return res;
  }
};

Data parse(string& s, int& pos) {
  assert(pos < s.size());
  if (s[pos] == '(') {
    pos++;
    string empty{};
    Data res(empty);
    while (s[pos] != ')') {
      var parsed = parse(s, pos);
      res = res + parsed;
    }
    pos++;
    return res;
  }
  if ('0' <= s[pos] && s[pos] <= '9') {
    ll cnt = 0;
    while ('0' <= s[pos] && s[pos] <= '9') {
      cnt = cnt * 10 + s[pos] - '0';
      pos++;
    }
    Data res = parse(s, pos);
    res = res * cnt;
    return res;
  }
  {
    var res_str = s.substr(pos, 1);
    Data res(res_str);
    pos++;
    return res;
  }
}

bool solve() {
  string s, q;
  cin >> s;
  if (s == "#") return false;
  cin >> q;
  Target = q;
  s = "(" + s + ")";
  int pos = 0;
  var res = parse(s, pos);
  cout << res.cnt << endl;
  return true;
}

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

  while (solve());
}
accuracy: 1
time_ms: 6940
memory_kb: 3404
final_rank: 17

code_snippet: #include<bits/stdc++.h>
using ll = long long;
#define var auto
const char newl = '\n';

using namespace std;

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; }

ll count_occurence(string& s, string& target) {
  ll cnt = 0;
  for (int i = target.size(); i <= s.size(); i++) {
    if (s.substr(i - target.size(), target.size()) == target) cnt++;
  }
  return cnt;
}

string substr_from_end(string& s, ll len) {
  return s.substr(s.size() - len);
}


string Target;
struct Data {
  bool has_after;
  string prev;
  string after;
  ll cnt;

  Data(string prev, string after, ll cnt) : has_after(true), prev(prev), after(after), cnt(cnt){}
  Data(string s) : has_after(false), prev(s), after(), cnt(0) {}

  Data operator+(Data a) {
    ll new_cnt = cnt + a.cnt;
    if (!has_after) {
      var new_prev = prev + a.prev;
      new_cnt += count_occurence(new_prev, Target);
      if (a.has_after) {
        assert(Target.size() - 1 <= new_prev.size());
        return Data(new_prev.substr(0, Target.size() - 1), a.after, new_cnt);
      }
      else {
        if (Target.size() <= new_prev.size()) {
          return Data(new_prev.substr(0, Target.size() - 1), substr_from_end(new_prev, Target.size() - 1), new_cnt);
        }
        else {
          return Data(new_prev);
        }
      }
    }
    else {
      string middle = after + a.prev;
      new_cnt += count_occurence(middle, Target);
      if (a.has_after) {
        return Data(prev, a.after, new_cnt);
      }
      else {
        assert(Target.size() - 1 <= middle.size());
        return Data(prev, substr_from_end(middle, Target.size() - 1), new_cnt);
      }
    }
    assert(false);
  }
  // kasu
  Data operator*(ll cnt) {
    Data res(""), tmp(*this);
    while (cnt) {
      if (cnt & 1) res = res + tmp;
      tmp = tmp + tmp;
      cnt >>= 1;
    }
    return res;
  }
};

Data parse(string& s, int& pos) {
  assert(pos < s.size());
  if (s[pos] == '(') {
    pos++;
    Data res("");
    while (s[pos] != ')') {
      res = res + parse(s, pos);
    }
    pos++;
    return res;
  }
  if ('0' <= s[pos] && s[pos] <= '9') {
    ll cnt = 0;
    while ('0' <= s[pos] && s[pos] <= '9') {
      cnt = cnt * 10 + s[pos] - '0';
      pos++;
    }
    Data res = parse(s, pos);
    res = res * cnt;
    return res;
  }
  {
    Data res(s.substr(pos, 1));
    pos++;
    return res;
  }
}

bool solve() {
  string s, q;
  cin >> s;
  if (s == "#") return false;
  cin >> q;
  Target = q;
  s = "(" + s + ")";
  int pos = 0;
  var res = parse(s, pos);
  cout << res.cnt << endl;
  return true;
}

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

  while (solve());
}
accuracy: 1
time_ms: 7280
memory_kb: 3796
final_rank: 19

code_snippet: #pragma GCC ta g("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//#include <atcoder/maxflow>
//using namespace atcoder;
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 510000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-9;
const int mod = 1e9 + 7;
//const int mod = 998244353;

vector<ll> zalgo(string s){
    ll n = s.size();
    vector<ll> z(n,0);
    z[0] = n;
    ll i = 1, j = 0;
    while(i < n){
        while(i+j < n && s[j] == s[i+j]) j++;
        if(j == 0){
            i++;
            continue;
        }
        z[i] = j;
        ll k = 1;
        while(k < j && k + z[k] < j){
            z[i+k] = z[k];
            k++;
        }
        i += k;
        j -= k;
    }
    return z;
}

using state = string::const_iterator;

struct dat{
    string l,r;
    ll num;
};

string s,t;
ll m;

void calc_res_and_tmp(dat &res, dat &tmp){
    string Z;
    string L = res.r;
    if(L.size() < m-1){
        int rest = m-1-(int)L.size();
        L = res.l.substr(max(0,(int)res.l.size()-rest)) + L;
    }
    if(L.size() == m) L.erase(L.begin());
    string R = tmp.l;
    if(R.size() == m) R.pop_back();
    Z = t + '#' + L + R;
    auto z = zalgo(Z);
    REP(i,m+1,z.size()) if(z[i] == m) res.num++;
}

ll calc_tmp_and_tmp(dat &tmp, ll M){
    ll res = 0;
    string S;
    if(tmp.l.size() == m){
        S = tmp.r;
        if(S.size() == m) S.erase(S.begin());
        if(S.size() < m-1){
            S = tmp.l.substr((int)tmp.l.size()-(m-1-S.size())) + S;
        }
        S += tmp.l;
        S.pop_back();
        S = t + '#' + S;
        auto z = zalgo(S);
        REP(i,m+1,z.size()) if(z[i] == m) res++;
        res *= M-1;
    }else{
        if(M * tmp.l.size() < m) return 0;
        while((int)S.size() < m) S += tmp.l;
        S += tmp.l;
        S = t + '#' + S;
        auto z = zalgo(S);
        ll tot = M * tmp.l.size() - (m - tmp.l.size());
        REP(i,m+1,m+tmp.l.size()+1){
            if(z[i] == m){
                res += (tot-(i-(m+1))) / (int)tmp.l.size();
            }
        }
    }
    return res;
}

void merge_string(dat &res, dat &tmp){
    string S = tmp.l + tmp.r;
    int now = 0;
    while(res.l.size() < m && now < S.size()) res.l.push_back(S[now]), now++;
    S = S.substr(now);
    if(S.size() >= m) res.r = S.substr((int)S.size()-m);
    else{
        int rest = m - (int)S.size();
        res.r = res.r.substr(max(0,(int)res.r.size()-rest)) + S;
    }
}

ll num(state &b){
    ll res = 0;
    while(isdigit(*b)) res = res * 10 + *b - '0', b++;
    return res;
}

dat expr(state &b){
    dat res;
    res.num = 0;
    while(1){
        if(isdigit(*b)){
            ll M = num(b);
            dat tmp;
            tmp.num = 0;
            if(*b == '('){
                b++;
                tmp = expr(b);
                assert(*b == ')');
                b++;
                res.num += calc_tmp_and_tmp(tmp,M);
                if(tmp.l.size() == m){
                    if(M >= 2){
                        int rest = m - tmp.r.size();
                        tmp.r = tmp.l.substr(tmp.l.size()-rest) + tmp.r;
                    }
                    assert(tmp.r.size() == m);
                }else{
                    if(M * tmp.l.size() <= m*2){
                        string s;
                        rep(i,M) s += tmp.l;
                        if(s.size() <= m){
                            tmp.l = s;
                        }else{
                            tmp.l = s.substr(0,m);
                            tmp.r = s.substr(m);
                        }
                    }else{
                        string s,t;
                        string tm = tmp.l;
                        reverse(all(tm));
                        while(s.size() < m){
                            s += tmp.l;
                            t += tm;
                        }
                        while(s.size() > m){
                            s.pop_back();
                            t.pop_back();
                        }
                        assert(s.size() == m);
                        assert(t.size() == m);
                        reverse(all(t));
                        tmp.l = s;
                        tmp.r = t;
                    }
                }
            }else{
                rep(j,min(M,m)) tmp.l.push_back(*b);
                if(M>m) rep(j,min(m,M-m)) tmp.r.push_back(*b);
                if(t == tmp.l && M >= m){
                    res.num += M-m+1;
                }
                b++;
            }
            res.num += tmp.num * M;
            calc_res_and_tmp(res,tmp);
            merge_string(res,tmp);
        }else if(isupper(*b)){
            if(res.l.size() < m){
                res.l.push_back(*b);
                if(res.l == t) res.num++;
            }else{
                if(res.r.size() < m){
                    res.r.push_back(*b);
                    int sz = res.r.size();
                    string tmp = res.l.substr(sz) + res.r;
                    if(tmp == t) res.num++;
                }else{
                    res.r.push_back(*b);
                    res.r.erase(res.r.begin());
                    if(res.r == t) res.num++;
                }
            }
            b++;
        }else{
            break;
        }
    }
    //debug(res.l,res.num,res.r);
    return res;
}

int main(){
    while(1){
        cin >> s;
        if(s == "#") break;
        cin >> t;
        m = t.size();
        state b = s.begin();
        cout << expr(b).num << "\n";
    }
}
accuracy: 1
time_ms: 190
memory_kb: 3596
final_rank: 1

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

#define rep(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define ALL(v) (v).begin(),(v).end()
using ll=long long int;
const int inf = 0x3fffffff; const ll INF = 0x1fffffffffffffff; const double eps=1e-12;
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;}

vector<int> z_algo(string s){
   int n=s.size(); vector<int> res(n);
   for(int i=1,j=0;i<n;i++){
      if(i+res[i-j]<j+res[j])res[i]=res[i-j];
      else{
         int k=max(0,j+res[j]-i);
         while(i+k<n&&s[k]==s[i+k])k++;
         res[i]=k; j=i;
      }
   } res[0]=n; return res;
}

string tar;
struct X{
   ll ret=0;
   string L,R;
   X(string s=""){
      L=R=s;
      auto seq=z_algo(tar+s);
      rep(i,tar.size(),seq.size())if(seq[i]>=tar.size()){
         ret++;
      }
   }
};
X merge(X& a,X& b){
   X res;
   res.ret=a.ret+b.ret;
   if(tar.size()>1){
      auto seq=z_algo(tar+a.R+b.L);
      rep(i,tar.size(),seq.size())if(seq[i]>=tar.size())res.ret++;
   }
   res.L=a.L;
   if(a.L.size()<tar.size()-1){
      res.L+=b.L;
      if(res.L.size()>tar.size()-1){
         res.L.resize(tar.size()-1);
      }
   }
   res.R=b.R;
   if(res.R.size()<tar.size()-1){
      res.R=a.R+res.R;
      if(res.R.size()>tar.size()-1){
         reverse(ALL(res.R));
         res.R.resize(tar.size()-1);
         reverse(ALL(res.R));
      }
   }
   return res;
}
X times(X a,ll t){
   X res;
   while(t){
      if(t&1)res=merge(res,a);
      a=merge(a,a);
      t>>=1;
   }
   return res;
}

typedef string::const_iterator State;
X Genome(State& beg);
X Letter(State& beg);
ll Number(State& beg);

X Genome(State& beg){
   X ret;
   for(;;){
      if(isdigit(*beg)){
         ll t=Number(beg);
         if((*beg)=='('){
            beg++; // '('
            X add=Genome(beg);
            beg++; // ')'
            add=times(add,t);
            ret=merge(ret,add);
         }
         else{
            X add=Letter(beg);
            add=times(add,t);
            ret=merge(ret,add);
         }
      }
      else if('A'<=(*beg) and (*beg)<='Z'){
         X add=Letter(beg);
         ret=merge(ret,add);
      }
      else break;
   }
   return ret;
}
X Letter(State& beg){
   string ret;
   ret+=(*beg);
   beg++;
   return ret;
}
ll Number(State& beg){
   ll ret=0;
   while(isdigit(*beg)){
      ret*=10;
      ret+=(*beg)-'0';
      beg++;
   }
   return ret;
}


void solve(){
   string s;
   cin>>s;
   if(s=="#")exit(0);
   cin>>tar;

   State it=s.begin();
   X ans=Genome(it);
   cout<<ans.ret<<'\n';
}

int main(){
   for(;;)solve();
   return 0;
}
accuracy: 1
time_ms: 3160
memory_kb: 3596
final_rank: 12