#include <bits/stdc++.h>
using namespace std;
const int MAX = 55;
int n, m;
char ar[55][55];
bool isVisited[55][55];
void setUp() {
  for (int i = 0; i < MAX; i++) {
    for (int j = 0; j < MAX; j++) {
      isVisited[i][j] = false;
    }
  }
}
char X;
bool check = false;
void dfs(int i, int j) {
  queue<int> current;
  current.push(i);
  current.push(j);
  isVisited[i][j] = true;
  int p = 1;
  while (!current.empty()) {
    int i_temp = current.front();
    current.pop();
    int j_temp = current.front();
    current.pop();
    if (!p)
      if (isVisited[i_temp][j_temp] == true) {
        check = true;
        break;
      }
    isVisited[i_temp][j_temp] = true;
    p = 0;
    if (i_temp >= 0 && j_temp - 1 >= 0) {
      if (isVisited[i_temp][j_temp - 1] == true)
        ;
      else if (X == ar[i_temp][j_temp - 1]) {
        current.push(i_temp);
        current.push(j_temp - 1);
      }
    }
    if (i_temp - 1 >= 0 && j_temp >= 0) {
      if (isVisited[i_temp - 1][j_temp] == true)
        ;
      else if (X == ar[i_temp - 1][j_temp]) {
        current.push(i_temp - 1);
        current.push(j_temp);
      }
    }
    if (i_temp + 1 < n) {
      if (isVisited[i_temp + 1][j_temp] == true)
        ;
      else if (X == ar[i_temp + 1][j_temp]) {
        current.push(i_temp + 1);
        current.push(j_temp);
      }
    }
    if (j_temp + 1 < m) {
      if (isVisited[i_temp][j_temp + 1] == true)
        ;
      else if (X == ar[i_temp][j_temp + 1]) {
        current.push(i_temp);
        current.push(j_temp + 1);
      }
    }
  }
}
int main(void) {
  setUp();
  cin >> n >> m;
  for (int i = 0; i < n; i++) cin >> ar[i];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (isVisited[i][j] == false) {
        X = ar[i][j];
        dfs(i, j);
      }
      if (check == true) break;
    }
    if (check == true) break;
  }
  if (check == true)
    cout << "Yes" << endl;
  else
    cout << "No" << endl;
  return 0;
}
