#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 50;
const int maxm = 1e6 + 50;
const double eps = 1e-10;
const int max_index = 62;
const int inf = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
inline int read() {
  char c = getchar();
  while (!isdigit(c)) c = getchar();
  int x = 0;
  while (isdigit(c)) {
    x = x * 10 + c - '0';
    c = getchar();
  }
  return x;
}
const int offset = 2000;
struct Point {
  int x, y;
  Point(int x = 0, int y = 0) : x(x), y(y) {}
  bool operator<(const Point &rhs) const {
    if (x == rhs.x) return y < rhs.y;
    return x < rhs.x;
  }
} P[205];
std::vector<int> G[maxm];
int n, m;
int dis[maxm], vis[maxm];
int get(int x, int y) { return x * m + y; }
int ans = 0;
void dfs(int u) {
  vis[u] = 1;
  int res = 0;
  for (int i = 0; i < G[u].size(); i++) {
    int v = G[u][i];
    if (vis[v]) {
      puts("Poor Inna!");
      exit(0);
    }
    if (!dis[v]) dfs(v);
    res = max(res, dis[v]);
  }
  dis[u] = res + 1;
  vis[u] = 0;
}
int dir[4][2] = {0, -1, -1, 0, 0, 1, 0, -1};
char mp[1005][1005];
bool judge(char x, char y) {
  bool ok = 0;
  ok |= (x == 'D' && y == 'I');
  ok |= (x == 'I' && y == 'M');
  ok |= (x == 'M' && y == 'A');
  ok |= (x == 'A' && y == 'D');
  return ok;
}
int main() {
  n = read(), m = read();
  for (int i = 0; i < n; i++) scanf("%s", mp[i]);
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      int u = get(i, j);
      for (int k = 0; k < 2; k++) {
        int dx = i + dir[k][0], dy = j + dir[k][1];
        if (dx < 0 || dy < 0) continue;
        int v = get(dx, dy);
        if (judge(mp[dx][dy], mp[i][j])) {
          G[v].push_back(u);
        } else if (judge(mp[i][j], mp[dx][dy])) {
          G[u].push_back(v);
        }
      }
    }
  }
  for (int i = 0; i < m * n; i++) {
    int x = i / m, y = i % m;
    if (mp[x][y] != 'D') continue;
    dfs(i);
    ans = max(ans, dis[i]);
  }
  if (ans < 4)
    puts("Poor Dima!");
  else
    printf("%d\n", ans / 4);
  return 0;
}
