Problem

There is a puzzle game where you move curling stones and stack them exactly on the goal square. The detailed rules are as follows.

The field consists of H × W squares, with stones placed in some squares at the beginning. There is only one goal square, and no stone is placed on the goal square from the beginning. In addition, the field is surrounded by an outer wall, so stones will not jump out of the field on the way.

Players can choose one stone for each move and launch it in either the up, down, left, or right direction to slide it. A slipping stone will continue to slide until it hits another stone or the outer wall of the field. If it hits another stone, the stone on the hit side will be recoiled and will slide in a chain in the same direction as the first shot.

For example, when stone A is launched to the right in the state of FIG. 1, the final state is as shown in FIG.

Figure 1


Figure 1





Figure 2


Figure 2





The condition for clearing this puzzle is to place one of the stones on the field exactly on the goal square. It will not be cleared if you pass the goal square.

Your job is to create a program that takes the initial state of the field as input and outputs whether the puzzle is clear or not.

Constraints

* 1 ≤ H ≤ 16
* 1 ≤ W ≤ 16
* 2 ≤ H x W ≤ 256
* Guaranteed to have only one goal square
* Guaranteed to have at least one square with curling stones on it

Input

The input is given in the following format.


H W
F11 F12 ... F1W
F21 F22 ... F2W
...
FH1 FH2 ... FHW


Fij is either'.',' O', or'@', and each has the following meaning. (1 ≤ i ≤ H, 1 ≤ j ≤ W)

*'.': Blank cell
*'o': The square on which the curling stone is placed
*'@': Goal square

Output

Print "yes" or "no" (not including "") on one line to see if the puzzle is clear.

Examples

Input

1 10
o........@


Output

yes


Input

3 6
......
.o..@.
......


Output

no


Input

6 4
....
.oo.
.oo.
....
.@..
....


Output

yes
#include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;

bool solve(vector<string>ini_field,int gx,int gy) {
	set<vector<string>>memo;
	memo.emplace(ini_field);
	queue<vector<string>>que;
	que.push(ini_field);
	int dx[] = { -1,0,1,0 };
	int dy[] = { 0,1,0,-1 };
	while (!que.empty()) {
		auto field(que.front());
		que.pop();
		for (int y = 0; y < field.size(); ++y) {
			for (int x = 0; x < field[0].size(); ++x) {
				if (field[y][x] == 'o') {
					if(y==gy&&x==gx)return true;
					for (int way = 0; way < 4; ++way) {
						auto nextfield(field);
						int nx(x);
						int ny(y);
						while (true) {
							const int next_x=nx+dx[way];
							const int next_y=ny+dy[way];
							if (next_x >= 0 && next_x < field[0].size() &&
								next_y >= 0 && next_y < field.size()) {
								swap(nextfield[ny][nx],nextfield[next_y][next_x]);
							}
							else {
								break;
							}
							nx=next_x;
							ny=next_y;
						}
						if (memo.find(nextfield) == memo.end()) {
							memo.emplace(nextfield);
							que.push(nextfield);
						}
					}
				}
			}
		}
	}
	return false;
}

int main() {
	int H,W;cin>>H>>W;
	vector<string>field;
	vector<pair<int,int>>curs;
	int gx,gy;
	for (int i = 0; i < H; ++i) {
		string st;cin>>st;
		field.push_back(st);
		for (int j = 0; j < W; ++j) {
			auto ch(st[j]);
			{
				if (ch == 'o') {
					curs.push_back(make_pair(i,j));
				}
				else if (ch == '@') {
					gx=j;
					gy=i;
					field[i][j]='.';
				}
			}
		}
	}
	bool ok=false;
	 if (curs.size() >= 3&&H>1&&W>1) {
		ok=true;
	 }
	 else {
		 ok=solve(field,gx,gy);
	 }
	if(ok)cout<<"yes"<<endl;
	else cout<<"no"<<endl;
	return 0;
}