#include <bits/stdc++.h>   using namespace std;   const int Mo = 998244353;   const int N = 2e5 + 50;   const int md = 998244353;   inline void add(int &x, int y) {     x += y;     if (x >= md) {       x -= md;     }   }   inline void sub(int &x, int y) {     x -= y;     if (x < 0) {       x += md;     }   }   inline int mul(int x, int y) { return (long long)x * y % md; }   inline int power(int x, int y) {     int res = 1;     for (; y; y >>= 1, x = mul(x, x)) {       if (y & 1) {         res = mul(res, x);       }     }     return res;   }   inline int inv(int a) {     a %= md;     if (a < 0) {       a += md;     }     int b = md, u = 0, v = 1;     while (a) {       int t = b / a;       b -= t * a;       swap(a, b);       u -= t * v;       swap(u, v);     }     if (u < 0) {       u += md;     }     return u;   }   namespace ntt {   int base = 1, root = -1, max_base = -1;   vector<int> rev = {0, 1}, roots = {0, 1};   void init() {     int temp = md - 1;     max_base = 0;     while (temp % 2 == 0) {       temp >>= 1;       ++max_base;     }     root = 2;     while (true) {       if (power(root, 1 << max_base) == 1 &&           power(root, 1 << max_base - 1) != 1) {         break;       }       ++root;     }   }   void ensure_base(int nbase) {     if (max_base == -1) {       init();     }     if (nbase <= base) {       return;     }     assert(nbase <= max_base);     rev.resize(1 << nbase);     for (int i = 0; i < 1 << nbase; ++i) {       rev[i] = rev[i >> 1] >> 1 | (i & 1) << nbase - 1;     }     roots.resize(1 << nbase);     while (base < nbase) {       int z = power(root, 1 << max_base - 1 - base);       for (int i = 1 << base - 1; i < 1 << base; ++i) {         roots[i << 1] = roots[i];         roots[i << 1 | 1] = mul(roots[i], z);       }       ++base;     }   }   void dft(vector<int> &a) {     int n = a.size(), zeros = __builtin_ctz(n);     ensure_base(zeros);     int shift = base - zeros;     for (int i = 0; i < n; ++i) {       if (i < rev[i] >> shift) {         swap(a[i], a[rev[i] >> shift]);       }     }     for (int i = 1; i < n; i <<= 1) {       for (int j = 0; j < n; j += i << 1) {         for (int k = 0; k < i; ++k) {           int x = a[j + k], y = mul(a[j + k + i], roots[i + k]);           a[j + k] = (x + y) % md;           a[j + k + i] = (x + md - y) % md;         }       }     }   }   vector<int> multiply(vector<int> a, vector<int> b) {     int need = a.size() + b.size() - 1, nbase = 0;     while (1 << nbase < need) {       ++nbase;     }     ensure_base(nbase);     int sz = 1 << nbase;     a.resize(sz);     b.resize(sz);     bool equal = a == b;     dft(a);     if (equal) {       b = a;     } else {       dft(b);     }     int inv_sz = inv(sz);     for (int i = 0; i < sz; ++i) {       a[i] = mul(mul(a[i], b[i]), inv_sz);     }     reverse(a.begin() + 1, a.end());     dft(a);     a.resize(need);     return a;   }   }  // namespace ntt   using ntt::multiply;   vector<int> &operator*=(vector<int> &a, const vector<int> &b) {     if (min(a.size(), b.size()) < 128) {       vector<int> c = a;       a.assign(a.size() + b.size() - 1, 0);       for (int i = 0; i < c.size(); ++i) {         for (int j = 0; j < b.size(); ++j) {           add(a[i + j], mul(c[i], b[j]));         }       }     } else {       a = multiply(a, b);     }     return a;   }   vector<int> operator*(const vector<int> &a, const vector<int> &b) {     vector<int> c = a;     return c *= b;   }   int val[26], p[26];   char s[N], t[N];   long long ans[N];   vector<int> A, B, C;   int a[5][N], b[5][N];   int main(int argc, const char *argv[]) {     srand((unsigned)time(0));     for (int i = 0; i < 26; i++) {       val[i] = rand() % Mo;       int x;       scanf( %d , &x);       p[x - 1] = i;     }     scanf( %s , s);     int ls = (int)strlen(s);     scanf( %s , t);     int lt = (int)strlen(t);     for (int i = 0; i < lt; i++) {       int id = t[i] -  a ;       long long u = val[id], v = val[p[id]];       a[4][i] = 1;       a[3][i] = (-2 * u - 2 * v) % Mo;       a[2][i] = (u * u % Mo + v * v % Mo + 4 * u * v % Mo) % Mo;       a[1][i] = -2 * u * v % Mo * (u + v) % Mo;       a[0][i] = u * u % Mo * v % Mo * v % Mo;       for (int j = 0; j < 5; j++) {         if (a[j][i] < 0) {           a[j][i] += Mo;         }       }     }     for (int i = 0; i < ls; i++) {       int id = s[i] -  a ;       long long u = val[id];       b[0][i] = 1;       for (int j = 1; j < 5; j++) {         b[j][i] = u * b[j - 1][i] % Mo;       }     }     for (int i = 0; i < 5; i++) {       A = std::vector<int>(a[i], a[i] + lt);       reverse(b[i], b[i] + ls);       B = std::vector<int>(b[i], b[i] + ls);       C = A * B;       for (int j = ls - 1; j < lt; j++) {         ans[j] += C[j];       }     }     for (int j = ls - 1; j < lt; j++) {       putchar(ans[j] % Mo == 0 ?  1  :  0 );     }     putchar(10);     return 0;   }