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)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] input = Console.ReadLine().Split(' ');
            int mapH = int.Parse(input[0]);

            string[] map = new string[mapH];

            for (int i = 0; i < mapH; i++)
            {
                map[i] = Console.ReadLine();
            }

            input = Console.ReadLine().Split(' ');
            int patH = int.Parse(input[0]);
            int patW = int.Parse(input[1]);

            string[] pat = new string[patH];

            for (int i = 0; i < patH; i++)
            {
                pat[i] = Console.ReadLine();
            }

            KMP kmp = new KMP();

            List<int> candidateIndex;
            int max = mapH - patH;

            StringBuilder sb = new StringBuilder();

            for (int i = 0; i <= max; i++)
            {
                candidateIndex = kmp.SearchString(map[i], pat[0]);

                foreach (var index in candidateIndex)
                {
                    bool isSame = true;

                    for (int j = 1; j < patH; j++)
                    {
                        if (!isSame) continue;

                        for (int k = 0; k < patW; k++)
                        {
                            if (map[i + j][index + k] != pat[j][k])
                            {
                                isSame = false;
                                break;
                            }
                        }
                    }
                    if (isSame) sb.AppendLine(i + " " + index);
                }
            }
            Console.Write(sb);
        }
    }

    class KMP
    {
        int[] lps;

        public List<int> SearchString(string text, string pattern)
        {
            List<int> ret = new List<int>();

            int M = pattern.Length;
            int N = text.Length;
            int i = 0;
            int j = 0;

            ComputeLPS(pattern, M);

            while (i < N)
            {
                if (pattern[j] == text[i])
                {
                    j++;
                    i++;
                }

                if (j == M)
                {
                    ret.Add(i - j);
                    j = lps[j - 1];
                }

                else if (i < N && pattern[j] != text[i])
                {
                    if (j != 0) j = lps[j - 1];
                    else i++;
                }
            }

            return ret;
        }

        private void ComputeLPS(string pattern, int M)
        {
            lps = new int[M];
            lps[0] = 0;

            int len = 0;
            int i = 1;

            while (i < M)
            {
                if (pattern[i] == pattern[len])
                {
                    len++;
                    lps[i] = len;
                    i++;
                }
                else
                {
                    if (len != 0)
                    {
                        len = lps[len - 1];
                    }
                    else
                    {
                        lps[i] = 0;
                        i++;
                    }
                }
            }
        }
    }
}