text: data()); } int main() { int tH; int tW; while (~scanf("%d%d", &tH, &tW)) { vector<string> table(tH); for (int(i) = 0; (i) < (int)(tH); ++(i)) { char buf[401]; scanf("%s", buf); table[i] = buf; } int pH; int pW; scanf("%d%d", &pH, &pW); vector<string> pattern(pH); for (int(i) = 0; (i) < (int)(pH); ++(i)) { char buf[401]; scanf("%s", buf); pattern[i] = buf; } int H = tH + pH, W = tW + pW; int logh = 1, logw = 1; while (1 << logh < H) ++logh; while (1 << logw < W) ++logw; vector<vector<int>> matches(tH, vector<int>(tW, 0)); for (int a = 0; a < 26; a += 2) { vector<vector<Ring>> A(1 << logh, vector<Ring>(1 << logw)), B = A; for (int(i) = 0; (i) < (int)(tH + pH); ++(i)) for (int(j) = 0; (j) < (int)(tW + pW); ++(j)) { char c = table[i % tH][j % tW]; int x = c == 'a' + a, y = c == 'a' + (a + 1); A[tH + pH - 1 - i][tW + pW - 1 - j] = complex<double>(x, y); } for (int(i) = 0; (i) < (int)(pH); ++(i)) for (int(j) = 0; (j) < (int)(pW); ++(j)) { char c = pattern[i][j]; int x = c == 'a' + a, y = c == 'a' + (a + 1); B[i][j] = complex<double>(x, -y); } FFT2D(logh, H, logw, W, A); FFT2D(logh, H, logw, W, B); for (int(i) = 0; (i) < (int)(1 << logh); ++(i)) for (int(j) = 0; (j) < (int)(1 << logw); ++(j)) A[i][j] *= B[i][j]; FFT2Dinv(logh, H, logw, W, A); for (int(i) = 0; (i) < (int)(tH); ++(i)) for (int(j) = 0; (j) < (int)(tW); ++(j)) { Ring r = A[tH + pH - 1 - i][tW + pW - 1 - j]; matches[i][j] += (int)round(r.real()); } } int qs = 0; for (int(i) = 0; (i) < (int)(pH); ++(i)) for (int(j) = 0; (j) < (int)(pW); ++(j)) qs += pattern[i][j] == '?'; for (int(i) = 0; (i) < (int)(tH); ++(i)) for (int(j) = 0; (j) < (int)(tW); ++(j)) matches[i][j] += qs; vector<string> ans(tH, string(tW, '?')); for (int(i) = 0; (i) < (int)(tH); ++(i)) for (int(j) = 0; (j) < (int)(tW); ++(j)) ans[i][j] = matches[i][j] == pH * pW ?'1' : '0'; for (int(i) = 0; (i) < (int)(tH); ++(i)) puts(ans[i].c_str()); } return 0; }