#include <bits/stdc++.h>
using namespace std;
struct Node {
  int x, y, step, d;
};
int dir[4][2] = {-1, 0, 0, 1, 1, 0, 0, -1};
char mp[55][55];
int step[55][55];
bool vis[55][55];
int n, m;
bool isok(int x, int y) {
  if (x >= 0 && x < n && y >= 0 && y < m) return true;
  return false;
}
bool bfs(int x, int y) {
  Node st, now;
  queue<Node> Q;
  while (!Q.empty()) Q.pop();
  st.x = x;
  st.y = y;
  st.step = 0;
  st.d = -1;
  Q.push(st);
  step[x][y] = 0;
  vis[x][y] = true;
  while (!Q.empty()) {
    st = Q.front();
    Q.pop();
    for (int i = 0; i < 4; i++) {
      if (st.d == (i + 2) % 4) continue;
      now.x = st.x + dir[i][0];
      now.y = st.y + dir[i][1];
      now.step = st.step + 1;
      now.d = i;
      if (isok(now.x, now.y) && mp[st.x][st.y] == mp[now.x][now.y]) {
        if (vis[now.x][now.y] && (now.step + step[now.x][now.y] + 1) >= 4) {
          return true;
        }
        if (!vis[now.x][now.y]) {
          vis[now.x][now.y] = true;
          step[now.x][now.y] = now.step;
          Q.push(now);
        }
      }
    }
  }
  return false;
}
bool solve() {
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      if (!vis[i][j] && bfs(i, j)) return true;
  return false;
}
int main() {
  while (~scanf("%d%d", &n, &m)) {
    for (int i = 0; i < n; i++) scanf("%s", mp[i]);
    memset(vis, false, sizeof(vis));
    memset(step, 0, sizeof(step));
    if (solve())
      printf("Yes\n");
    else
      printf("No\n");
  }
  return 0;
}
