Problem:
Pattern Search

Find places where a R × C pattern is found within a H × W region. Print top-left coordinates (i, j) of sub-regions where the pattern found. The top-left and bottom-right coordinates of the region is (0, 0) and (H-1, W-1) respectively.

Input

In the first line, two integers H and W are given. In the following H lines, i-th lines of the region are given.

In the next line, two integers R and C are given. In the following R lines, i-th lines of the pattern are given.

output

For each sub-region found, print a coordinate i and j separated by a space character in a line. Print the coordinates in ascending order of the row numbers (i), or the column numbers (j) in case of a tie.

Constraints

1 ≤ H, W ≤ 1000

1 ≤ R, C ≤ 1000

The input consists of alphabetical characters and digits

Sample Input 1

4 5
00010
00101
00010
00100
3 2
10
01
10

Sample Output 1

0 3
1 2

Solution in C (judge verdict: Time Limit Exceeded)

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <limits.h>


/*
 * ?????????????´¢????????????rolling-hash???
 * String????????????????????¨??????Pattern????????????????????????
 * ??????????±???????????????°???????????°????????????????????£??¬??????????????????
 *
 */

char String[1001][1001];
char Pattern[1001][1001];




/*
 * unsinged long long?????¨???????????¨??§???????????????????????????????????????????????? mod (2<<64)??¨??????????????¨????????????
 * P????????¨????????????(2<<64)??¨?´???§???????????????????????§????????????????????¶
 */
typedef unsigned long long ull;
#define P (1000000007)

ull power[1000001];

/*
 * String:????´¢????±??????????
 * s_num:????´¢????±???????????????????
 * Pattern:????´¢??????????????????
 * p_num:????´¢???????????????????????????
 */
void rolling_hash(int h, int w, int r, int c)
{
    int i, j, k , l;
    ull target_hash = 0, Pattern_hash = 0;
    
    
    /*
     * target hash??????????¨?????????¨?????????????????????????±?????????????
     */
    power[0] = 1;
    for (i=0; i <r*c; i++) {
            power[i+1]= power[i]* P;
    }
    
    /*
     * Pattern??????????????\???????±???????
     */
    for (i=0; i < r; i++) {
        for (j=0; j < c; j++) {
            Pattern_hash += Pattern[i][j] * power[i*c + j];
        }
    }
    
    
    for (i = 0; i + r <= h; i++) {
        
        /*
         * String???????????\???????±???????
         */
        target_hash = 0;
        for (k=0; k < r; k++) {
            for (l=0; l < c; l++) {
                target_hash += String[k+i][l] * power[c * k  + l] ;
            }
        }
        
        for (j=0; j+c <= w; j++) {
            /*
             * hash???????????´????????°?????????????????¨????????????
             */
            if (target_hash == Pattern_hash) {
                printf("%d %d\n", i, j);
            }
            
            
            /*
             * target???????????????????????????????????????????????????????????????????????\??????????¨??????????
             */
            if (j+c != w) {
                target_hash = 0;
                for (k=0; k < r; k++) {
                    for (l=0; l < c; l++) {
                        target_hash += String[i+k][l+j+1] * power[k*c + l] ;
                    }
                }
            }

        }
    }
    
    return;
}


int main( ){
    
    int i, j, H, W, R,C;
    scanf("%d", &H);
    scanf("%d", &W);
    getchar();
    for (i = 0; i < H ; i++) {
        for (j = 0; j < W; j++) {
            scanf("%c", &String[i][j]);
        }
        getchar();
    }
    
    scanf("%d", &R);
    scanf("%d", &C);
    getchar();
    for (i = 0; i < R ; i++) {
        for (j = 0; j < C; j++) {
            scanf("%c", &Pattern[i][j]);
        }
        getchar();
    }
    
    rolling_hash(H, W, R, C);
   
    
    return 0;
}