#include <bits/stdc++.h>
using namespace std;
template <typename F, typename S>
ostream& operator<<(ostream& os, const pair<F, S>& p) {
  return os << "(" << p.first << ", " << p.second << ")";
}
template <class T>
ostream& operator<<(ostream& os, vector<T> const& x) {
  os << "{ ";
  for (auto& y : x) os << y << " ";
  return os << "}";
}
template <class T>
ostream& operator<<(ostream& os, set<T> const& x) {
  os << "{ ";
  for (auto& y : x) os << y << " ";
  return os << "}";
}
template <typename T>
ostream& operator<<(ostream& os, const multiset<T>& v) {
  os << "[";
  typename multiset<T>::const_iterator it;
  for (it = v.begin(); it != v.end(); it++) {
    if (it != v.begin()) os << ", ";
    os << *it;
  }
  return os << "]";
}
template <typename F, typename S>
ostream& operator<<(ostream& os, const map<F, S>& v) {
  os << "[";
  typename map<F, S>::const_iterator it;
  for (it = v.begin(); it != v.end(); it++) {
    if (it != v.begin()) os << ", ";
    os << it->first << " = " << it->second;
  }
  return os << "]";
}
const long long int MOD = 1e9 + 7;
const int N = 2000 + 10;
long long int n, m;
string s[N];
vector<int> v1, v2;
template <class T>
inline T bigmod(T p, T e, T M) {
  long long int ret = 1;
  for (; e > 0; e >>= 1) {
    if (e & 1) ret = (ret * p) % M;
    p = (p * p) % M;
  }
  return (T)ret;
}
template <class T>
inline T modinverse(T a, T M) {
  return bigmod(a, M - 2, M);
}
int has2[205][N];
struct HASHING {
  long long int MOD;
  int N, B;
  vector<int> has, inv, power;
  HASHING(int _N, int _B, long long int _M) {
    N = _N;
    B = _B;
    MOD = _M;
    has.resize(N);
    inv.resize(N);
    power.resize(N);
    inv[0] = 1, inv[1] = modinverse((long long int)B, MOD);
    power[0] = 1;
    power[1] = power[0] * 1ll * B % MOD;
    for (int i = 2; i < N; ++i) {
      inv[i] = inv[i - 1] * 1LL * inv[1] % MOD;
      power[i] = power[i - 1] * 1ll * B % MOD;
    }
  }
  inline int range(int l, int r, int idx) {
    int ret = (has2[idx][r + 1] - has2[idx][l]) * 1ll * inv[l] % MOD;
    if (ret < 0) ret += MOD;
    return ret;
  }
  void gen(vector<int>& v, int cmd, int idx) {
    if (cmd == 1) {
      for (int i = 0; i < m; ++i)
        has[i + 1] = (has[i] + power[i] * 1ll * (s[idx][i] - 'a' + 1)) % MOD;
      v.emplace_back(has[m]);
    } else {
      for (int i = 0; i < n; ++i)
        has2[idx][i + 1] =
            (has2[idx][i] + power[i] * 1ll * (s[idx][i] - 'a' + 1)) % MOD;
    }
  }
} * h1, *h2;
void computeLPSArray(vector<int>& pat, vector<int>& lps) {
  int len = 0, i = 1;
  lps[0] = 0;
  while (i < pat.size()) {
    if (pat[i] == pat[len]) {
      len++;
      lps[i++] = len;
    } else {
      if (len != 0)
        len = lps[len - 1];
      else
        lps[i++] = 0;
    }
  }
}
bool KMPSearch(vector<int>& pat, vector<int>& txt) {
  int M = pat.size();
  int N = txt.size();
  vector<int> lps(M);
  computeLPSArray(pat, lps);
  int i = 0, j = 0;
  while (i < N) {
    if (pat[j] == txt[i]) i++, j++;
    if (j == M) {
      cout << i - j + 1 << " ";
      return true;
      j = lps[j - 1];
    } else if (i < N && pat[j] != txt[i]) {
      if (j != 0)
        j = lps[j - 1];
      else
        i = i + 1;
    }
  }
  return false;
}
bool go(int idx) {
  vector<int> v;
  for (int i = 0; i < m; i++) {
    v.emplace_back(h1->range(idx, idx + m - 1, i));
  }
  if (KMPSearch(v, v1)) {
    cout << idx + 1 << "\n";
    return true;
  }
  return false;
}
void _main_main() {
  cin >> n >> m;
  h1 = new HASHING(N, 29, MOD);
  for (int i = 0; i < n; i++) cin >> s[i];
  for (int i = 0; i < n; i++) h1->gen(v1, 1, i);
  for (int i = 0; i < m; i++) cin >> s[i];
  for (int i = 0; i < m; i++) h1->gen(v2, 2, i);
  for (int i = 0; i + m - 1 < n; i++)
    if (go(i)) break;
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int testCase = 1;
  for (int i = 0; i < testCase; i++) {
    _main_main();
  }
}
