#include <iostream>
#include <vector>
#include <unordered_map>
#include <bitset>
#include <cstring>

constexpr uint32_t p = 998244353;
typedef uint32_t *flagmap;

bool isflag(int a, int b, int c, int d)
{
    return a == 0 && b == 1 && c ==2 && d == 1;
}

void populateNoFlags(const std::vector<uint32_t> &grid, flagmap *fm, int cur, int m, uint32_t hash)
{
    if(cur == m)
    {
        fm[0][hash] = 1;
        return;
    }

    if(grid[cur] == 3)
    {
        for(uint64_t j=0; j<3; j++)
        {   
            uint64_t newhash = hash;
            newhash |= (j << (2*cur));
            populateNoFlags(grid, fm, cur+1, m, newhash);
        }
    }
    else
    {
        hash |= (grid[cur] << (2*cur));
        populateNoFlags(grid, fm, cur+1, m, hash);
    }
}

bool validHash(uint32_t hash, int m)
{
    for(int i=0; i<m; i++)
    {
        if( ((hash >> (2*i)) & 3U) == 3U)
            return false;
    }
    return true;
}

int main()
{
    int n, m;
    std::cin >> n >> m;
    int questionmarks = 0;
    std::vector<uint32_t> grid(n*m);
    for(int i=0; i<n*m; i++)
    {
        char c;
        std::cin >> c;
        if(c == 'I')
            grid[i] = 0;
        else if(c == 'C')
            grid[i] = 1;
        else if(c == 'P')
            grid[i] = 2;        
        else
        {
            grid[i] = 3;
            questionmarks++;
        }
    }
    
    uint32_t mapsize = (1U << (2*m));
    flagmap noflags[3];
    flagmap newnoflags[3];
    for(int i=0; i<3; i++)
    {
        noflags[i] = new uint32_t[mapsize];
        newnoflags[i] = new uint32_t[mapsize];
    }
    
    for(int i=0; i<3; i++)
    {
        std::memset(noflags[i], 0, mapsize * sizeof(int32_t));
    }

    populateNoFlags(grid, noflags, 0, m, 0);
    
    for(int row=1; row<n; row++)
    {
        {
            for(int i=0; i<3; i++)
            {
                std::memset(newnoflags[i], 0, mapsize * sizeof(int32_t));
            }

            for(int prev=0; prev<3; prev++)
            {
                for(uint32_t hash = 0; hash < mapsize; hash++)
                {
                    if(!validHash(hash, m))
                        continue;
                    uint32_t newhash = hash;
                    newhash &= ~(3U);
                    for(uint32_t j = 0; j<3; j++)
                    {
                        if(grid[row*m] == j || grid[row*m] == 3)
                        {
                            newnoflags[hash & 3][newhash | j] = (newnoflags[hash & 3][newhash | j] + noflags[prev][hash]) % p;
                        }                       
                    }
                }
            }
            for(int i=0; i<3; i++)
            {
                std::swap(noflags[i], newnoflags[i]);
            }
        }
        for(int col = 1; col < m; col++)
        {
            for(int i=0; i<3; i++)
            {
                std::memset(newnoflags[i], 0, mapsize * sizeof(int32_t));
            }


            for(int prev=0; prev<3; prev++)
            {
                for(uint32_t hash = 0; hash < mapsize; hash++)
                {
                    if(!validHash(hash, m))
                        continue;

                    uint32_t newhash = hash;
                    newhash &= ~(3U << (2*col));
                    for(uint32_t j = 0; j<3; j++)
                    {            
                        if(grid[row*m+col] == j || grid[row*m+col] == 3)
                        {
                            if(!isflag(prev, (hash >> (2*col)) & 3U, (hash >> (2*(col-1))) & 3U, j))
                            {
                                newnoflags[(hash >> (2*col)) & 3U][newhash | (j << (2*col))] = (newnoflags[(hash >> (2*col)) & 3U][newhash | (j << (2*col))] + noflags[prev][hash]) % p;
                            }
                        }
                    }
                }
            }
            for(int i=0; i<3; i++)
            {
                std::swap(noflags[i], newnoflags[i]);
            }
        }
    }
    uint32_t tot = 1;
    for(int i=0; i<questionmarks; i++)
    {
        tot = (tot * 3) % p;
    }
    uint32_t finalflags = 0;
    for(int j=0; j<3; j++)
    {
        for(uint32_t hash = 0; hash < mapsize; hash++)
        {
            if(validHash(hash, m))
                finalflags = (finalflags + noflags[j][hash]) % p;
        }
    }
    
    uint32_t finalanswer = (tot + p - finalflags) % p;
    
    std::cout << finalanswer << std::endl;
}
