/*
	Problem: 	Puzzle
	Author:		Jan Kotas
	Algorithm:	recurse, restrains
	Complexity:	exponential
*/

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

#define bool int
#define true 1
#define false 0

int m,n,mn,pieces_count,basic_count;
int pieces[36];
int usage[36];

int puzzle[8][8];

bool try_it(int i, int j)
{
	int first, last, next_i, next_j, mask, value, k;

	if(puzzle[i][j+1] == -1)
	{
		next_i = i;
		next_j = j+1;
	}
	else
	if(puzzle[i+1][j] == -1)
	{
		next_i = i+1;
		next_j = j;
	}
	else
	if(puzzle[i][j-1] == -1)
	{
		next_i = i;
		next_j = j-1;
	}
	else
	if(puzzle[i-1][j] == -1)
	{
		next_i = i-1;
		next_j = j;
	}
	else
	{
		next_i = 0;
	}

	if((i == 1) || (i == n) || (j == 1) || (j == m))
	{
		first = basic_count;
		last = pieces_count;
	}
	else
	{
		first = 0;
		last = basic_count;
	}

	mask = 0;
	value = 0;

	if(puzzle[i-1][j] != -1)
	{
		value |= (~puzzle[i-1][j] & 0x30) >> 4;
		mask  |= 0x03;		
	}

	if(puzzle[i+1][j] != -1)
	{
		value |= (~puzzle[i+1][j] & 0x03) << 4;
		mask  |= 0x30;		
	}

	if(puzzle[i][j-1] != -1)
	{
		value |= (~puzzle[i][j-1] & 0x0c) << 4;
		mask  |= 0xc0;		
	}

	if(puzzle[i][j+1] != -1)
	{
		value |= (~puzzle[i][j+1] & 0xc0) >> 4;
		mask  |= 0x0c;		
	}

	for(k = first; k < last; k++)
	{
		if(!usage[k])
			continue;

		if((pieces[k] & mask) == value)
		{
			puzzle[i][j] = pieces[k];
			usage[k]--;

			if(!next_i || try_it(next_i, next_j)) return true;

			usage[k]++;
			puzzle[i][j] = -1;;
		}
	}

	return false;
}

bool simple_check()
{
	int a[4][4];
	int i,j;

	memset(a, 0, sizeof(a));

	for(i = 0; i < mn; i++)
	{
		for(j = 0; j < 4; j++)
			a[j][(pieces[i] >> (2*j)) & 3]++;
	}

	return
		(a[0][0] == m) && (a[2][0] == m) &&
		(a[1][0] == n) && (a[3][0] == n) &&
		(a[0][1] == a[2][2]) && (a[0][2] == a[2][1]) &&
		(a[1][1] == a[3][2]) && (a[1][2] == a[3][1]);
}

static int not_basic_piece(int v)
{
	return !(v & 0x03) || !(v & 0x0c) || !(v & 0x30) || !(v & 0xc0);
}

static int cmp_piece(const void *a, const void *b)
{
	int av = *(const int*)a;
	int bv = *(const int*)b;

	int af = not_basic_piece(av);
	int bf = not_basic_piece(bv);

	return (af != bf) ? (af - bf) : (av - bv);
}

bool do_it()
{
	int i, j;

	if(!simple_check())
		return false;

	qsort(pieces, mn, sizeof(pieces[0]), cmp_piece);

	usage[0] = 1;

	for(i = 1, j = 0; i < mn; i++)
	{
		if(pieces[i] == pieces[j])
		{
			usage[j]++;
			continue;
		}

		pieces[++j] = pieces[i];
		usage[j] = 1;
	}

	pieces_count = ++j;

	for(i = 0; /* i < j */; i++)
		if(not_basic_piece(pieces[i]))
			break;

	basic_count = i;

	/* create restrains */

	for(j = 0; j <= m + 1; j++)
		puzzle[n+1][j] = puzzle[0][j] = 0xff;

	for(i = 1; i <= n; i++)
	{
		puzzle[i][m+1] = puzzle[i][0] = 0xff;			

		for(j = 1; j <= m; j++)
			puzzle[i][j] = -1;
	}

	/* go! */

	return try_it(1,1);
}

char s[8];
int map[256];

int main()
{
	int i,j,r;

	map['F'] = 0;
	map['I'] = 1;
	map['O'] = 2;

	for(;;)
	{
		scanf("%d%d\n", &n, &m);
		if(!n || !m) break;

		mn = m*n;

		for(i = 0; i < mn; i++)
		{
			scanf("%s", s);

			r = 0;

			for(j = 0; j < 4; j++)
				r |= map[(int)s[j]] << (2 * j);

			pieces[i] = r;
		}

		printf(do_it() ? "YES\n" : "NO\n");
	}
	return 0;
}
