B - Seek Grid
Source: atcoder
Difficulty: 200

Problem Statement
You are given an
N \times N
grid
S
and an
M \times M
grid
T
. The cell at the
i
-th row from the top and the
j
-th column from the left is denoted by
(i,j)
.
The colors of the cells in
S
and
T
are represented by
N^2
characters
S_{i,j}
(
1\leq i,j\leq N
) and
M^2
characters
T_{i,j}
(
1\leq i,j\leq M
), respectively. In grid
S
, cell
(i,j)
is white if
S_{i,j}
is
.
, and black if
S_{i,j}
is
#
. The same applies for grid
T
.
Find
T
within
S
. More precisely, output integers
a
and
b
(
1 \leq a,b \leq N-M+1
) that satisfy the following condition:
S_{a+i-1,b+j-1} = T_{i,j}
for every
i,j
(
1\leq i,j \leq M
).
Constraints
1 \leq M \leq N \leq 50
N
and
M
are integers.
Each of
S_{i,j}
and
T_{i,j}
is
.
or
#
.
There is exactly one pair
(a,b)
satisfying the condition.
Input
The input is given from Standard Input in the following format:
N
M
S_{1,1}S_{1,2}\dots S_{1,N}
S_{2,1}S_{2,2}\dots S_{2,N}
\vdots
S_{N,1}S_{N,2}\dots S_{N,N}
T_{1,1}T_{1,2}\dots T_{1,M}
T_{2,1}T_{2,2}\dots T_{2,M}
\vdots
T_{M,1}T_{M,2}\dots T_{M,M}
Output
Print
a
and
b
in this order, separated by a space on one line.
Sample Input 1
3 2
#.#
..#
##.
.#
#.
Sample Output 1
2 2
The
2 \times 2
subgrid of
S
from the 2nd to the 3rd row and from the 2nd to the 3rd column matches
T
.
Sample Input 2
2 1
#.
##
.
Sample Output 2
1 2

C++ solution:
#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>

#include <algorithm>
using namespace std;

#define rep(i, s, limit) for (int i = (int)s; i < (int)limit; i++)

int main() {
    int N, M;
    cin >> N >> M;

    vector<string> S(N, (string())), T(M, (string()));

    rep(i, 0, N) cin >> S[i];
    rep(i, 0, M) cin >> T[i];

    rep(a, 0, N - M + 1) {
        rep(b, 0, N - M + 1) {
            if (S[a][b] != T[0][0]) continue;
            bool is_match = 1;
            rep(i, 0, M) {
                rep(j, 0, M) {
                    if (S[a + i][b + j] != T[i][j]) {
                        is_match = 0;
                        break;
                    }
                }
            }
            if (is_match) cout << a + 1 << " " << b + 1 << endl;
            // if (S[a + i - 1][b + j - 1] == T[i][j]) }
        }
    }
}

Go solution:
package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"sort"
	"strconv"
)

var sc = bufio.NewScanner(os.Stdin)
var wr = bufio.NewWriter(os.Stdout)

func out(x ...interface{}) {
	fmt.Fprintln(wr, x...)
}

func outSlice[T any](s []T) {
	for i := 0; i < len(s)-1; i++ {
		fmt.Fprint(wr, s[i], " ")
	}
	fmt.Fprintln(wr, s[len(s)-1])
}

func getI() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func getF() float64 {
	sc.Scan()
	i, e := strconv.ParseFloat(sc.Text(), 64)
	if e != nil {
		panic(e)
	}
	return i
}

func getInts(N int) []int {
	ret := make([]int, N)
	for i := 0; i < N; i++ {
		ret[i] = getI()
	}
	return ret
}

func getS() string {
	sc.Scan()
	return sc.Text()
}

// min, max, asub, absなど基本関数
func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

// min for n entry
func nmin(a ...int) int {
	ret := a[0]
	for _, e := range a {
		ret = min(ret, e)
	}
	return ret
}

// max for n entry
func nmax(a ...int) int {
	ret := a[0]
	for _, e := range a {
		ret = max(ret, e)
	}
	return ret
}

func chmin(a *int, b int) bool {
	if *a < b {
		return false
	}
	*a = b
	return true
}

func chmax(a *int, b int) bool {
	if *a > b {
		return false
	}
	*a = b
	return true
}

func asub(a, b int) int {
	if a > b {
		return a - b
	}
	return b - a
}

func abs(a int) int {
	if a >= 0 {
		return a
	}
	return -a
}

func lowerBound(a []int, x int) int {
	idx := sort.Search(len(a), func(i int) bool {
		return a[i] >= x
	})
	return idx
}

func upperBound(a []int, x int) int {
	idx := sort.Search(len(a), func(i int) bool {
		return a[i] > x
	})
	return idx
}

func main() {
	defer wr.Flush()
	sc.Split(bufio.ScanWords)
	sc.Buffer([]byte{}, math.MaxInt32)
	// this template is new version.
	// use getI(), getS(), getInts(), getF()
	N, M := getI(), getI()
	s := make([]string, N)
	for i := 0; i < N; i++ {
		s[i] = getS()
	}
	t := make([]string, M)
	for i := 0; i < M; i++ {
		t[i] = getS()
	}

	for a := 0; a < N-M+1; a++ {
		for b := 0; b < N-M+1; b++ {
			ok := true
			for i := 0; i < M; i++ {
				for j := 0; j < M; j++ {
					if s[a+i][b+j] != t[i][j] {
						ok = false
						break
					}
				}
			}
			if ok {
				out(a+1, b+1)
				return
			}
		}
	}

}

Java solution:
import java.io.*;
import java.util.HashMap;
import java.util.StringTokenizer;

public class Main {
    static class MyScanner {
        static BufferedReader r;
        static StringTokenizer st;
        public MyScanner() {
            r = new BufferedReader(new InputStreamReader(System.in));
        }
        public String next() {
            try {
                while (st == null || !st.hasMoreTokens()) {
                    st = new StringTokenizer(r.readLine());
                }
                return st.nextToken();
            } catch (Exception e) {
                return null;
            }
        }
        public int nextInt() {
            return Integer.parseInt(next());
        }
        public long nextLong() {
            return Long.parseLong(next());
        }
        public double nextDouble() {
            return Double.parseDouble(next());
        }
    }
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static MyScanner sc = new MyScanner();
    static final int MAXN = 55;
    static int N, M;
    static char[][] s = new char[MAXN][], t = new char[MAXN][];
    public static void main(String[] args) throws IOException {
        N = sc.nextInt();
        M = sc.nextInt();
        for (int i = 0; i < N; i++) {
            s[i] = sc.next().toCharArray();
        }
        for (int i = 0; i < M; i++) {
            t[i] = sc.next().toCharArray();
        }
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (check(i, j)) {
                    System.out.println((i + 1) + " " + (j + 1));
                    return;
                }
            }
        }
    }

    private static boolean check(int x, int y) {
        if (N - x < M || N - y < M) return false;
        for (int i = x; i < x + M; i++) {
            for (int j = y; j < y + M; j++) {
                if (s[i][j] != t[i - x][j - y]) return false;
            }
        }
        return true;
    }
}

JavaScript solution:
function main(input) {
  const lines = input.trim().split("\n");
  const [n, m] = lines[0].split(" ").map(Number);
  const arrayN = lines.slice(1, n + 1).map((row) => row.split(""));
  const arrayM = lines.slice(n + 1, n + m + 1).map((row) => row.split(""));

  for (let a = 0; a <= n - m; a++) {
    for (let b = 0; b <= n - m; b++) {
      let match = true;
      for (let i = 0; i < m; i++) {
        for (let j = 0; j < m; j++) {
          if (arrayN[a + i][b + j] !== arrayM[i][j]) {
            match = false;
            break;
          }
        }
        if (!match) break;
      }
      if (match) {
        console.log(a + 1, b + 1); 
        return;
      }
    }
  }
}

main(require("fs").readFileSync("/dev/stdin", "utf8"));

Python solution:
N, M = map(int, input().split())

n_grid = []

for _ in range(N):
    row = list(input())
    n_grid.append(row)

m_grid = []
for _ in range(M):
    row = list(input())
    m_grid.append(row)


def find_sub_matrix(nx, ny):
    for my in range(M):
        for mx in range(M):
            if m_grid[my][mx] != n_grid[my + ny][mx + nx]:
                return False
    return True

def solve():
    for ny in range(N):
        row = n_grid[ny]
        for nx in range(N):
            colour = row[nx]
            if colour == m_grid[0][0] and nx + M <= N and ny + M <= N:
                if find_sub_matrix(nx, ny):
                    print(ny + 1, nx + 1)
                    return

solve()

Ruby solution:
n, m = gets.chomp.split(" ").map(&:to_i)
s = []
t = []
n.times do
  s << gets.chomp.split("")
end
m.times do
  t << gets.chomp.split("")
end

(n - m + 1).times do |si|
  (n - m + 1).times do |sj|
    match = true

    m.times do |ti|
      m.times do |tj|
        if s[si + ti][sj + tj] != t[ti][tj]
          match = false
          break
        end
      end
      break unless match
    end

    if match
      puts "#{si + 1} #{sj + 1}"
      exit
    end
  end
end