#include <bits/stdc++.h>
using namespace std;
struct Node {
  int v, nex;
} Edge[4000005];
int n, m;
int zl[4][2] = {{1, 0}, {0, 1}, {0, -1}, {-1, 0}};
char s[1005][1005];
int h[1000005], stot;
void add(int u, int v) {
  Edge[++stot] = (Node){v, h[u]};
  h[u] = stot;
}
int dp[1000005], vis[1000005], id[1005][1005], G[1005][1005], sx[1000005], k;
int dfs(int u) {
  if (~dp[u]) return dp[u];
  int tmp = 0;
  for (int i = h[u]; i; i = Edge[i].nex) {
    int v = Edge[i].v;
    if (vis[v])
      tmp = 0x3f3f3f3f;
    else {
      vis[v] = 1;
      int QAQ = dfs(v);
      vis[v] = 0;
      tmp = max(tmp, QAQ);
    }
  }
  return dp[u] = tmp + 1;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) scanf("%s", s[i] + 1);
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      id[i][j] = (i - 1) * m + j;
      if (s[i][j] == 'D')
        G[i][j] = 1, sx[++k] = id[i][j];
      else if (s[i][j] == 'I')
        G[i][j] = 2;
      else if (s[i][j] == 'M')
        G[i][j] = 3;
      else if (s[i][j] == 'A')
        G[i][j] = 4;
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      for (int k = 0; k < 4; k++) {
        int x = i + zl[k][0], y = j + zl[k][1];
        if (x >= 1 && x <= n && y >= 1 && y <= m) {
          if (G[x][y] == G[i][j] + 1 || (G[i][j] == 4 && G[x][y] == 1))
            add(id[i][j], id[x][y]);
        }
      }
    }
  }
  memset(dp, -1, sizeof(dp));
  int num = 0;
  for (int i = 1; i <= k; i++) {
    vis[sx[i]] = 1;
    int tmp = dfs(sx[i]);
    vis[sx[i]] = 0;
    num = max(num, tmp / 4);
  }
  if (num > 0x3f3f3f3f / 4)
    printf("Poor Inna!\n");
  else if (num == 0)
    printf("Poor Dima!\n");
  else
    printf("%d", num);
  return 0;
}
