8 10
cwcwcwcwcw
crcrcrcrcr
cwcwcwcwcw
crcrcrcrcr
cwcwcwcwcw
crcrcrcrcr
cwcwcwcwcw
crcrcrcrcr
12 14
?????r??c?????
?????w????cw?w
??????cr????c?
c?????c??????w
c???????????c?
??c?????cw????
????c?c?c?????
c?????????c???
c?????c?????c?
??????????c??w
?r????c??r????
???w?w??c???c?

0000000000
1010101010
0000000000
1010101010
0000000000
1010101010
0000000000
1010101010

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update

using namespace std;
using namespace __gnu_pbds;

//data structure (fenwick substitute)
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define pb push_back
#define eb emplace_back
#define mp make_pair
#define pii pair<int, int>
#define vi vector<int>
#define pll pair<ll, ll>
#define fi first
#define se second
#define ull uint64_t
#define ll int64_t

//debugging snippets
#define Local freopen("input","r",stdin)
#define tr1(x)                cerr << #x << ": " << x << endl;
#define tr2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
#define tr3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
#define tr4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;

struct kmp {
    vector<int> pfunc;
    string needle;
    int state;

    void build(const string & s) {
        needle = s;
        int n = needle.size();
        pfunc.resize(n, 0);
        int match = 0;
        for (int i = 1; i < n; ++i) {
            while (1) {
                if (needle[i] == '?' || needle[match] == '?' || needle[match] == needle[i]) {
                    match++;
                    break;
                } else if (match == 0) break;
                else match = pfunc[match - 1];
            }
            pfunc[i] = match;
        }
    }

    void reset() {
        state = 0;
    }

    void feed(char ch) {
        if (state == needle.size()) {
            state = pfunc[state - 1];
        }
        while (1) {
            if (needle[state] == '?' || needle[state] == ch) {
                state++;
                break;
            } else if (state == 0) break;
            else state = pfunc[state - 1];
        }
    }
    
    bool lastMatched() const {
        return state == needle.size();
    }
};

string grid[800];
string pattern[400];

bool ans[400][400];

int main() {
    Local;
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < n; ++i) {
        cin >> grid[i];
    }
    int r, c;
    cin >> r >> c;
    for (int i = 0; i < r; ++i) {
        cin >> pattern[i];
    }
    kmp matcher[c];
    for (int i = 0; i < c; ++i) {
        string pat;
        for (int j = 0; j < r; ++j) {
            pat += pattern[j][i];
        }
        matcher[i].build(pat);
    }
    for (int col = 0; col < m; ++col) {
        for (int i = 0; i < c; ++i) {
            matcher[i].reset();
        }
        for (int row = 0; row < n + r - 1; ++row) {
            //feed character to kmp
            for (int i = 0; i < c; ++i) {
                matcher[i].feed(grid[row % n][(col + i) % m]);
            }
            if (row >= r - 1) {
                ans[row - (r - 1)][col] = 1;
                for (int i = 0; i < c; ++i) {
                    ans[row - (r - 1)][col] &= matcher[i].lastMatched();
                }
            }
        }
    }
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cout << ans[i][j];
        }
        cout << '\n';
    }
    return 0;
}
