#include <bits/stdc++.h>
using namespace std;

/*

  WTF :| !!

*/

vector<string>s;
vector<vector<int> > mem;
map<char, char>mp;
int n, m, vis[1003][1003], ans;
int dx[] = {1, -1, 0, 0},
    dy[] = {0, 0, 1, -1};

bool cyc(int a, int b) {
  if(s[a][b] == 'D' and vis[a][b] == 1) {
    return 1;
  }
  bool ret = 0;
  vis[a][b] = 1;
  for(int i = 0;i < 4;i++) {
    int x = a + dx[i], y = b + dy[i];
    if(x >= 0 and x < n and y >= 0 and y < m and mp[s[a][b]] == s[x][y] and vis[x][y] != 2) {
      ret |= cyc(x, y);
    }
  }
  vis[a][b] = 2;
  return ret;
}

int path(int a, int b) {
  if(vis[a][b] != -1) {
    return vis[a][b];
  }
  int ret = 1;
  for(int i = 0;i < 4;i++) {
    int x = a + dx[i], y = b + dy[i];
    if(x >= 0 and x < n and y >= 0 and y < m and mp[s[a][b]] == s[x][y]) {
      int tmp = vis[x][y];
      if(tmp == -1)
        ret = max(ret, path(x, y) + 1);
      else
        ret = max(ret, tmp + 1);
    }
  }
  return vis[a][b] = ret;
}

int main() {
  mp['D'] = 'I';
  mp['I'] = 'M';
  mp['M'] = 'A';
  mp['A'] = 'D';
  cin >> n >> m;
  s.resize(n);
  mem.resize(n);
  for(int i = 0;i < n;i++) {
    cin >> s[i];
    mem[i].resize(m);
    for(int j = 0;j < m;j++) {
      mem[i][j] = 0;
    }
  }
  for(int i = 0;i < n;i++) {
    for(int j = 0;j < m;j++) {
      if(s[i][j] == 'D' and !mem[i][j]) {
        if(cyc(i, j)) {
          puts("Poor Inna!");
          return 0;
        }
      }
    }
  }
  memset(vis, -1, sizeof vis);
  for(int i = 0;i < n;i++) {
    for(int j = 0;j < m;j++) {
      if(s[i][j] == 'D' and vis[i][j] == -1) {
        ans = max(ans, path(i, j)/4);
      }
    }
  }
  if(ans == 0) {
    puts("Poor Dima!");
  } else {
    cout << ans << endl;
  }
  return 0;
}


#include <bits/stdc++.h>
using namespace std;

vector<string>s;
vector<vector<int> > mem;
map<char, char>mp;
int ans, n, m, sx, sy;
int dx[] = {1, -1, 0, 0},
    dy[] = {0, 0, 1, -1};

bool cyc(int a, int b) {
  mem[a][b] = 1;
  bool ret = 0;
  for(int i = 0;i < 4 and !ret;i++) {
    int x = a + dx[i], y = b + dy[i];
    if(x >= 0  and x < n and y >= 0 and y < m and s[x][y] == mp[s[a][b]]) {
      if(mem[x][y] and x == sx and y == sy) {
        return 1;
      }
      ret |= cyc(x, y);
    }
  }
  return ret;
}

int path(int a, int b) {
  if(mem[a][b] != -1) {
    return mem[a][b];
  }
  int ret = 1;
  for(int i = 0;i < 4;i++) {
    int x = a + dx[i], y = b + dy[i];
    if(x >= 0 and x < n and y >= 0 and y < m and mp[s[a][b]] == s[x][y]) {
      int tmp = mem[x][y];
      if(tmp == -1)
        ret = max(ret, path(x, y) + 1);
      else
        ret = max(ret, tmp + 1);
    }
  }
  return mem[a][b] = ret;
}

int main() {
  mp['D'] = 'I';
  mp['I'] = 'M';
  mp['M'] = 'A';
  mp['A'] = 'D';
  cin >> n >> m;
  s.resize(n);
  mem.resize(n);
  for(int i = 0;i < n;i++) {
    cin >> s[i];
    mem[i].resize(m);
    for(int j = 0;j < m;j++) {
      mem[i][j] = 0;
    }
  }
  for(int i = 0;i < n;i++) {
    for(int j = 0;j < m;j++) {
      if(s[i][j] == 'D' and !mem[i][j]) {
        sx = i;
        sy = j;
        if(cyc(i, j)) {
          puts("Poor Inna!");
          return 0;
        }
      }
    }
  }
  for(int i = 0;i < n;i++) {
    for(int j = 0;j < m;j++) {
      mem[i][j] = -1;
    }
  }
  for(int i = 0;i < n;i++) {
    for(int j = 0;j < m;j++) {
      if(s[i][j] == 'D' and mem[i][j] == -1) {
        ans = max(ans, path(i, j) / 4);
        // cout << i << ' ' << j << ' ' << ans << endl;
      }
    }
  }
  if(ans == 0) {
    puts("Poor Dima!");
  } else {
    cout << ans << endl;
  }
  return 0;
}


#include <bits/stdc++.h>
using namespace std;

string s[1003];
int mem[1003][1003];
map<char, char>mp;
int ans, n, m;
int dx[] = {1, -1, 0, 0},
    dy[] = {0, 0, 1, -1};

bool cyc(int a, int b) {
  if(mem[a][b] and s[a][b] == 'D') {
    return 1;
  }
  mem[a][b] = 1;
  bool ret = 0;
  for(int i = 0;i < 4;i++) {
    int x = a + dx[i], y = b + dy[i];
    if(x >= 0  and x < n and y >= 0 and y < m and s[x][y] == mp[s[a][b]]) {
      ret |= cyc(x, y);
    }
  }
  return ret;
}

int path(int a, int b) {
  if(mem[a][b] != -1) {
    return mem[a][b];
  }
  int ret = 1;
  for(int i = 0;i < 4;i++) {
    int x = a + dx[i], y = b + dy[i];
    if(x >= 0 and x < n and y >= 0 and y < m and mp[s[a][b]] == s[x][y]) {
      ret = max(ret, path(x, y) + 1);
    }
  }
  return mem[a][b] = ret;
}

int main() {
  mp['D'] = 'I';
  mp['I'] = 'M';
  mp['M'] = 'A';
  mp['A'] = 'D';
  cin >> n >> m;
  for(int i = 0;i < n;i++) {
    cin >> s[i];
  }
  for(int i = 0;i < n;i++) {
    for(int j = 0;j < m;j++) {
      if(s[i][j] == 'D' and !mem[i][j]) {
        if(cyc(i, j)) {
          puts("Poor Inna!");
          return 0;
        }
      }
    }
  }
  memset(mem, -1, sizeof mem);
  for(int i = 0;i < n;i++) {
    for(int j = 0;j < m;j++) {
      if(s[i][j] == 'D' and mem[i][j] == -1) {
        ans = max(ans, path(i, j) / 4);
        // cout << i << ' ' << j << ' ' << ans << endl;
      }
    }
  }
  if(ans == 0) {
    puts("Poor Dima!");
  } else {
    cout << ans << endl;
  }
  return 0;
}


#include <bits/stdc++.h>
using namespace std;

vector<string>s;
vector<vector<int> > mem;
map<char, char>mp;
int ans, n, m, sx, sy;
int dx[] = {1, -1, 0, 0},
    dy[] = {0, 0, 1, -1};

bool cyc(int a, int b) {
  if(mem[a][b] and a == sx and b == sy) {
    return 1;
  }
  if(mem[a][b])
    return 0;
  mem[a][b] = 1;
  bool ret = 0;
  for(int i = 0;i < 4;i++) {
    int x = a + dx[i], y = b + dy[i];
    if(x >= 0  and x < n and y >= 0 and y < m and s[x][y] == mp[s[a][b]]) {
      ret |= cyc(x, y);
    }
  }
  return ret;
}

int path(int a, int b) {
  if(mem[a][b] != -1) {
    return mem[a][b];
  }
  int ret = 1;
  for(int i = 0;i < 4;i++) {
    int x = a + dx[i], y = b + dy[i];
    if(x >= 0 and x < n and y >= 0 and y < m and mp[s[a][b]] == s[x][y]) {
      int tmp = mem[x][y];
      if(tmp == -1)
        ret = max(ret, path(x, y) + 1);
      else
        ret = max(ret, tmp + 1);
    }
  }
  return mem[a][b] = ret;
}

int main() {
  mp['D'] = 'I';
  mp['I'] = 'M';
  mp['M'] = 'A';
  mp['A'] = 'D';
  cin >> n >> m;
  s.resize(n);
  mem.resize(n);
  for(int i = 0;i < n;i++) {
    cin >> s[i];
    mem[i].resize(m);
    for(int j = 0;j < m;j++) {
      mem[i][j] = 0;
    }
  }
  for(int i = 0;i < n;i++) {
    for(int j = 0;j < m;j++) {
      if(s[i][j] == 'D' and !mem[i][j]) {
        sx = i;
        sy = j;
        if(cyc(i, j)) {
          puts("Poor Inna!");
          return 0;
        }
      }
    }
  }
  for(int i = 0;i < n;i++) {
    for(int j = 0;j < m;j++) {
      mem[i][j] = -1;
    }
  }
  for(int i = 0;i < n;i++) {
    for(int j = 0;j < m;j++) {
      if(s[i][j] == 'D' and mem[i][j] == -1) {
        ans = max(ans, path(i, j) / 4);
        // cout << i << ' ' << j << ' ' << ans << endl;
      }
    }
  }
  if(ans == 0) {
    puts("Poor Dima!");
  } else {
    cout << ans << endl;
  }
  return 0;
}


#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <vector>

#define memc(a, x) memset(a,x,sizeof(a))
#define ll long long
#define irp(i, a, b) for(int i=a;i<b;i++)
#define drp(i, a, b) for(int i=a;i>b;i--)
#define CK cout<<'#'<<endl
#define CK2(a) cout<<'#'<<a<<endl

using namespace std;

const int maxn = 1009;
const int mmaxn = 1000009;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

char tb[maxn][maxn];
vector<int> edge[mmaxn];
int n, m;
int vis[mmaxn], deg[mmaxn];
bool rim;

int encode(int x, int y) {
    return x * n + y;
}

void init() {
    scanf("%d%d", &n, &m);
    irp(i, 0, n) {
        scanf("%s", tb[i]);
        for (int j = 0; tb[i][j]; j++) {
            switch (tb[i][j]) {
                case 'D':
                    tb[i][j] = 0;
                    break;
                case 'I':
                    tb[i][j] = 1;
                    break;
                case 'M':
                    tb[i][j] = 2;
                    break;
                case 'A':
                    tb[i][j] = 3;
                    break;
            }
        }
    }
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            int nx, ny;
            irp(k, 0, 4) {
                nx = x + dx[k];
                ny = y + dy[k];
                if (nx >= 0 && nx < n && ny >= 0 && ny < m) {
                    if ((tb[x][y] + 1) % 4 == tb[nx][ny]) {
                        edge[cd].push_back(encode(nx, ny));
//                        deg[encode(nx, ny)]++;
                    }
                }
            }
        }
    }
}

bool dfs(int u) {
    vis[u] = -1;
    for (int x:edge[u]) {
        if (vis[x] == -1) {
            return true;
        }
        else if (vis[x] == 0 && dfs(x)) {
            return true;
        }
    }
    vis[u] = 1;
    return false;
}

int dfs2(int u) {
    vis[u] = -1;
    int ans = 0;
    for (int x:edge[u]) {
        if (vis[x] == 0) {
            ans = max(ans, dfs2(x));
        }
        else if (vis[x] == 1) {
            ans = max(ans, deg[x]);
        }
        else if (vis[x] == -1) {
            rim = true;
            return -1;
        }
    }
    vis[u] = 1;
    return deg[u] = ans + 1;
}

int main() {
//    freopen("input.txt", "r", stdin);
    init();
    memc(deg, 0);
    memc(vis, 0);
    int ans = 0;
    rim = false;
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            if (!rim && vis[cd] == 0 && tb[x][y] == 0) {
                ans = max(ans, dfs2(cd));
            }
        }
    }
    if (rim) {
        printf("Poor Inna!");
        return 0;
    }
    if (ans < 4) {
        printf("Poor Dima!");
        return 0;
    }
    printf("%d", ans / 4);
    return 0;
}


#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <vector>

#define memc(a, x) memset(a,x,sizeof(a))
#define ll long long
#define irp(i, a, b) for(int i=a;i<b;i++)
#define drp(i, a, b) for(int i=a;i>b;i--)
#define CK cout<<'#'<<endl
#define CK2(a) cout<<'#'<<a<<endl

using namespace std;

const int maxn = 1009;
const int mmaxn = 1000009;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

char tb[maxn][maxn];
vector<int> edge[mmaxn];
int n, m;
int vis[mmaxn];

int encode(int x, int y) {
    return x * n + y;
}

void init() {
    scanf("%d%d", &n, &m);
    irp(i, 0, n) {
        scanf("%s", tb[i]);
        for (int j = 0; tb[i][j]; j++) {
            switch (tb[i][j]) {
                case 'D':
                    tb[i][j] = 0;
                    break;
                case 'I':
                    tb[i][j] = 1;
                    break;
                case 'M':
                    tb[i][j] = 2;
                    break;
                case 'A':
                    tb[i][j] = 3;
                    break;
            }
        }
    }
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            int nx, ny;
            irp(k, 0, 4) {
                nx = x + dx[k];
                ny = y + dy[k];
                if (nx >= 0 && nx < n && ny >= 0 && ny < m) {
                    if ((tb[x][y] + 1) % 4 == tb[nx][ny]) {
                        edge[cd].push_back(encode(nx, ny));
                    }
                }
            }
        }
    }
}

int dfs(int u) {
    vis[u] = -1;
    for (int x:edge[u]) {
        if (vis[x] == -1) {
            return 1;
        }
        else if (vis[x] == 0) {
            if (dfs(x)) {
                return 1;
            }
        }
    }
    vis[u] = 1;
    return 0;
}

int dfs2(int u) {
    vis[u] = 1;
    int ans = 0;
    for (int x:edge[u]) {
        if (vis[x] == 0) {
            ans = max(ans, dfs2(x));
        }
    }
    return ans + 1;
}

int main() {
//    freopen("input.txt", "r", stdin);
    init();
    int fl = 0, mn = m * n;
    memc(vis, 0);
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            if (vis[cd] == 0 && tb[x][y] == 0 && dfs(cd) == 1) {
                printf("Poor Inna!");
                return 0;
            }
        }
    }
    memc(vis, 0);
    int ans = 0;
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            if (vis[cd] == 0 && tb[x][y] == 0) {
                ans = max(ans, dfs2(cd));
            }
        }
    }
    if (ans < 4) {
        printf("Poor Dima!");
        return 0;
    }
    printf("%d", ans / 4);
    return 0;
}


#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <vector>

#define memc(a, x) memset(a,x,sizeof(a))
#define ll long long
#define irp(i, a, b) for(int i=a;i<b;i++)
#define drp(i, a, b) for(int i=a;i>b;i--)
#define CK cout<<'#'<<endl
#define CK2(a) cout<<'#'<<a<<endl

using namespace std;

const int maxn = 1009;
const int mmaxn = 1000009;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

char tb[maxn][maxn];
vector<int> edge[mmaxn];
int n, m;
int vis[mmaxn], deg[mmaxn];
bool rim;

int encode(int x, int y) {
    return x * m + y;
}

void init() {
    scanf("%d%d", &n, &m);
    irp(i, 0, n) {
        scanf("%s", tb[i]);
    }
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            int nx, ny;
            irp(k, 0, 4) {
                nx = x + dx[k];
                ny = y + dy[k];
                if (nx >= 0 && nx < n && ny >= 0 && ny < m) {
                    if ((tb[x][y] == 'D' && tb[nx][ny] == 'I') ||
                        (tb[x][y] == 'I' && tb[nx][ny] == 'M') ||
                        (tb[x][y] == 'M' && tb[nx][ny] == 'A') ||
                        (tb[x][y] == 'A' && tb[nx][ny] == 'D')) {
                        edge[cd].push_back(encode(nx, ny));
                    }
                }
            }
        }
    }
}

bool dfs(int u) {
    vis[u] = -1;
    for (int x:edge[u]) {
        if (vis[x] == -1) {
            return true;
        }
        else if (vis[x] == 0 && dfs(x)) {
            return true;
        }
    }
    vis[u] = 1;
    return false;
}

int dfs2(int u) {
    vis[u] = -1;
    int ans = 0;
    for (int x:edge[u]) {
        if (vis[x] == 0) {
            ans = max(ans, dfs2(x));
        }
        else if (vis[x] == 1) {
            ans = max(ans, deg[x]);
        }
        else if (vis[x] == -1) {
            rim = true;
            return -1;
        }
    }
    vis[u] = 1;
    return deg[u] = ans + 1;
}

int main() {
//    freopen("input.txt", "r", stdin);
    init();
    memc(deg, 0);
    memc(vis, 0);
    int ans = 0;
    rim = false;
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            if (!rim && vis[cd] == 0 && tb[x][y] == 'D') {
                ans = max(ans, dfs2(cd));
            }
        }
    }
    if (rim) {
        printf("Poor Inna!");
        return 0;
    }
    if (ans < 4) {
        printf("Poor Dima!");
        return 0;
    }
    printf("%d", ans / 4);
    return 0;
}


#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <vector>

#define memc(a, x) memset(a,x,sizeof(a))
#define ll long long
#define irp(i, a, b) for(int i=a;i<b;i++)
#define drp(i, a, b) for(int i=a;i>b;i--)
#define CK cout<<'#'<<endl
#define CK2(a) cout<<'#'<<a<<endl

using namespace std;

const int maxn = 1009;
const int mmaxn = 1000009;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

char tb[maxn][maxn];
vector<int> edge[mmaxn];
int n, m;
int vis[mmaxn], deg[mmaxn];

int encode(int x, int y) {
    return x * n + y;
}

void init() {
    scanf("%d%d", &n, &m);
    irp(i, 0, n) {
        scanf("%s", tb[i]);
        for (int j = 0; tb[i][j]; j++) {
            switch (tb[i][j]) {
                case 'D':
                    tb[i][j] = 0;
                    break;
                case 'I':
                    tb[i][j] = 1;
                    break;
                case 'M':
                    tb[i][j] = 2;
                    break;
                case 'A':
                    tb[i][j] = 3;
                    break;
            }
        }
    }
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            int nx, ny;
            irp(k, 0, 4) {
                nx = x + dx[k];
                ny = y + dy[k];
                if (nx >= 0 && nx < n && ny >= 0 && ny < m) {
                    if ((tb[x][y] + 1) % 4 == tb[nx][ny]) {
                        edge[cd].push_back(encode(nx, ny));
//                        deg[encode(nx, ny)]++;
                    }
                }
            }
        }
    }
}

bool dfs(int u) {
    vis[u] = -1;
    for (int x:edge[u]) {
        if (vis[x] == -1) {
            return true;
        }
        else if (vis[x] == 0 && dfs(x)) {
            return true;
        }
    }
    vis[u] = 1;
    return false;
}

int dfs2(int u) {
    vis[u] = 1;
    int ans = 0;
    for (int x:edge[u]) {
        if (vis[x] == 0) {
            ans = max(ans, dfs2(x));
        }
        else if (vis[x] == 1) {
            ans = max(ans, deg[x]);
        }
    }
    return deg[u] = ans + 1;
}

int main() {
//    freopen("input.txt", "r", stdin);
    init();
    memc(vis, 0);
    memc(deg, 0);
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            if (vis[cd] == 0 && tb[x][y] == 0 && dfs(cd)) {
                printf("Poor Inna!");
                return 0;
            }
        }
    }
    memc(vis, 0);
    int ans = 0;
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            if (vis[cd] == 0 && tb[x][y] == 0) {
                ans = max(ans, dfs2(cd));
            }
        }
    }
    if (ans < 4) {
        printf("Poor Dima!");
        return 0;
    }
    printf("%d", ans / 4);
    return 0;
}


#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <vector>

#define memc(a, x) memset(a,x,sizeof(a))
#define ll long long
#define irp(i, a, b) for(int i=a;i<b;i++)
#define drp(i, a, b) for(int i=a;i>b;i--)
#define CK cout<<'#'<<endl
#define CK2(a) cout<<'#'<<a<<endl

using namespace std;

const int maxn = 1009;
const int mmaxn = 1000009;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

char tb[maxn][maxn];
vector<int> edge[mmaxn];
int n, m;
int vis[mmaxn], deg[mmaxn];
bool rim;

int encode(int x, int y) {
    return x * n + y;
}

void init() {
    scanf("%d%d", &n, &m);
    irp(i, 0, n) {
        scanf("%s", tb[i]);
    }
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            int nx, ny;
            irp(k, 0, 4) {
                nx = x + dx[k];
                ny = y + dy[k];
                if (nx >= 0 && nx < n && ny >= 0 && ny < m) {
                    if ((tb[x][y] == 'D' && tb[nx][ny] == 'I') ||
                        (tb[x][y] == 'I' && tb[nx][ny] == 'M') ||
                        (tb[x][y] == 'M' && tb[nx][ny] == 'A') ||
                        (tb[x][y] == 'A' && tb[nx][ny] == 'D')) {
                        edge[cd].push_back(encode(nx, ny));
                    }
                }
            }
        }
    }
}

bool dfs(int u) {
    vis[u] = -1;
    for (int x:edge[u]) {
        if (vis[x] == -1) {
            return true;
        }
        else if (vis[x] == 0 && dfs(x)) {
            return true;
        }
    }
    vis[u] = 1;
    return false;
}

int dfs2(int u) {
    vis[u] = -1;
    int ans = 0;
    for (int x:edge[u]) {
        if (vis[x] == 0) {
            ans = max(ans, dfs2(x));
        }
        else if (vis[x] == 1) {
            ans = max(ans, deg[x]);
        }
        else if (vis[x] == -1) {
            rim = true;
            return -1;
        }
    }
    vis[u] = 1;
    return deg[u] = ans + 1;
}

int main() {
//    freopen("input.txt", "r", stdin);
    init();
    memc(deg, 0);
    memc(vis, 0);
    int ans = 0;
    rim = false;
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            if (!rim && vis[cd] == 0 && tb[x][y] == 'D') {
                ans = max(ans, dfs2(cd));
            }
        }
    }
    if (rim) {
        printf("Poor Inna!");
        return 0;
    }
    if (ans < 4) {
        printf("Poor Dima!");
        return 0;
    }
    printf("%d", ans / 4);
    return 0;
}


#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <vector>

#define memc(a, x) memset(a,x,sizeof(a))
#define ll long long
#define irp(i, a, b) for(int i=a;i<b;i++)
#define drp(i, a, b) for(int i=a;i>b;i--)
#define CK cout<<'#'<<endl
#define CK2(a) cout<<'#'<<a<<endl

using namespace std;

const int maxn = 1009;
const int mmaxn = 1000009;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

char tb[maxn][maxn];
vector<int> edge[mmaxn];
int n, m;
int vis[mmaxn], deg[mmaxn];
bool rim;

int encode(int x, int y) {
    return x * n + y;
}

void init() {
    scanf("%d%d", &n, &m);
    irp(i, 0, n) {
        scanf("%s", tb[i]);
        irp(j, 0, m) {
            switch (tb[i][j]) {
                case 'D':
                    tb[i][j] = 0;
                    break;
                case 'I':
                    tb[i][j] = 1;
                    break;
                case 'M':
                    tb[i][j] = 2;
                    break;
                case 'A':
                    tb[i][j] = 3;
                    break;
            }
        }
    }
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            int nx, ny;
            edge[cd].clear();
            irp(k, 0, 4) {
                nx = x + dx[k];
                ny = y + dy[k];
                if (nx >= 0 && nx < n && ny >= 0 && ny < m) {
                    if ((tb[x][y] + 1) % 4 == tb[nx][ny]) {
                        edge[cd].push_back(encode(nx, ny));
                    }
                }
            }
        }
    }
}

int dfs(int u) {
    vis[u] = -1;
    for (int x:edge[u]) {
        if (vis[x] == -1) {
            rim = true;
            return 1;
        }
        if (vis[x] == 0 && dfs(x) == 1) {
            return 1;
        }
    }
    vis[u] = 1;
    return 0;
}

int dfs2(int u) {
    vis[u] = 1;
    int ans = 0;
    for (int x:edge[u]) {
        if (vis[x] == 0) {
            ans = max(ans, dfs2(x));
        }
        else if (vis[x] == 1) {
            ans = max(ans, deg[x]);
        }
    }
    return deg[u] = ans + 1;
}

int main() {
//    freopen("input.txt", "r", stdin);
    init();
    memc(vis, 0);
    memc(deg, 0);
    rim = false;
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            if (vis[cd] == 0 && tb[x][y] == 0) {
                dfs(cd);
                if (rim) {
                    printf("Poor Inna!");
                    return 0;
                }
            }
        }
    }
    memc(vis, 0);
    int ans = 0;
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            if (vis[cd] == 0 && tb[x][y] == 0) {
                ans = max(ans, dfs2(cd));
            }
        }
    }
    if (ans < 4) {
        printf("Poor Dima!");
        return 0;
    }
    printf("%d", ans / 4);
    return 0;
}


#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <vector>

#define memc(a, x) memset(a,x,sizeof(a))
#define ll long long
#define irp(i, a, b) for(int i=a;i<b;i++)
#define drp(i, a, b) for(int i=a;i>b;i--)
#define CK cout<<'#'<<endl
#define CK2(a) cout<<'#'<<a<<endl

using namespace std;

const int maxn = 1009;
const int mmaxn = 1000009;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

char tb[maxn][maxn];
vector<int> edge[mmaxn];
int n, m;
int vis[mmaxn], deg[mmaxn];

int encode(int x, int y) {
    return x * n + y;
}

void init() {
    scanf("%d%d", &n, &m);
    irp(i, 0, n) {
        scanf("%s", tb[i]);
        for (int j = 0; tb[i][j]; j++) {
            switch (tb[i][j]) {
                case 'D':
                    tb[i][j] = 0;
                    break;
                case 'I':
                    tb[i][j] = 1;
                    break;
                case 'M':
                    tb[i][j] = 2;
                    break;
                case 'A':
                    tb[i][j] = 3;
                    break;
            }
        }
    }
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            int nx, ny;
            irp(k, 0, 4) {
                nx = x + dx[k];
                ny = y + dy[k];
                if (nx >= 0 && nx < n && ny >= 0 && ny < m) {
                    if ((tb[x][y] + 1) % 4 == tb[nx][ny]) {
                        edge[cd].push_back(encode(nx, ny));
                        deg[encode(nx, ny)]++;
                    }
                }
            }
        }
    }
}

int dfs(int u) {
    vis[u] = -1;
    for (int x:edge[u]) {
        if (vis[x] == -1) {
            vis[u] = 1;
            return 1;
        }
        else if (vis[x] == 0) {
            if (dfs(x)) {
                vis[u] = 1;
                return 1;
            }
        }
    }
    vis[u] = 1;
    return 0;
}

int dfs2(int u) {
    vis[u] = 1;
    int ans = 0;
    for (int x:edge[u]) {
        if (vis[x] == 0) {
            ans = max(ans, dfs2(x));
        }
        else if (vis[x] == 1) {
            ans = max(ans, deg[x]);
        }
    }
    return deg[u] = ans + 1;
}

int main() {
//    freopen("input.txt", "r", stdin);
    init();
    memc(vis, 0);
    memc(deg, 0);
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            if (vis[cd] == 0 && tb[x][y] == 0 && dfs(cd) == 1) {
                printf("Poor Inna!");
                return 0;
            }
        }
    }
    memc(vis, 0);
    int ans = 0;
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            if (vis[cd] == 0 && tb[x][y] == 0) {
                ans = max(ans, dfs2(cd));
            }
        }
    }
    if (ans < 4) {
        printf("Poor Dima!");
        return 0;
    }
    printf("%d", ans / 4);
    return 0;
}


#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <vector>

#define memc(a, x) memset(a,x,sizeof(a))
#define ll long long
#define irp(i, a, b) for(int i=a;i<b;i++)
#define drp(i, a, b) for(int i=a;i>b;i--)
#define CK cout<<'#'<<endl
#define CK2(a) cout<<'#'<<a<<endl

using namespace std;

const int maxn = 1009;
const int mmaxn = 1000009;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

char tb[maxn][maxn];
vector<int> edge[mmaxn];
int n, m;
int vis[mmaxn], deg[mmaxn];
bool rim;

int encode(int x, int y) {
    return x * n + y;
}

void init() {
    scanf("%d%d", &n, &m);
    irp(i, 0, n) {
        scanf("%s", tb[i]);
        irp(j, 0, m) {
            switch (tb[i][j]) {
                case 'D':
                    tb[i][j] = 0;
                    break;
                case 'I':
                    tb[i][j] = 1;
                    break;
                case 'M':
                    tb[i][j] = 2;
                    break;
                case 'A':
                    tb[i][j] = 3;
                    break;
            }
        }
    }
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            int nx, ny;
            edge[cd].clear();
            irp(k, 0, 4) {
                nx = x + dx[k];
                ny = y + dy[k];
                if (nx >= 0 && nx < n && ny >= 0 && ny < m) {
                    if ((tb[x][y] + 1) % 4 == tb[nx][ny]) {
                        edge[cd].push_back(encode(nx, ny));
                    }
                }
            }
        }
    }
}

void dfs(int x) {
    if (rim) {
        return;
    }
    vis[x] = -1;
    for (int e:edge[x]) {
        if (vis[e] == 0) {
            dfs(e);
        }
        else if (vis[e] == -1) {
            rim = true;
            return;
        }
    }
    vis[x] = 1;
}

int dfs2(int u) {
    vis[u] = 1;
    int ans = 0;
    for (int x:edge[u]) {
        if (vis[x] == 0) {
            ans = max(ans, dfs2(x));
        }
        else if (vis[x] == 1) {
            ans = max(ans, deg[x]);
        }
    }
    return deg[u] = ans + 1;
}

int main() {
//    freopen("input.txt", "r", stdin);
    init();
    memc(vis, 0);
    memc(deg, 0);
    rim = false;
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            if (vis[cd] == 0 && tb[x][y] == 0) {
                dfs(cd);
                if (rim) {
                    printf("Poor Inna!");
                    return 0;
                }
            }
        }
    }
    memc(vis, 0);
    int ans = 0;
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            if (vis[cd] == 0 && tb[x][y] == 0) {
                ans = max(ans, dfs2(cd));
            }
        }
    }
    if (ans < 4) {
        printf("Poor Dima!");
        return 0;
    }
    printf("%d", ans / 4);
    return 0;
}


#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <vector>

#define memc(a, x) memset(a,x,sizeof(a))
#define ll long long
#define irp(i, a, b) for(int i=a;i<b;i++)
#define drp(i, a, b) for(int i=a;i>b;i--)
#define CK cout<<'#'<<endl
#define CK2(a) cout<<'#'<<a<<endl

using namespace std;

const int maxn = 1009;
const int mmaxn = 1000009;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

char tb[maxn][maxn];
vector<int> edge[mmaxn];
int n, m;
int vis[mmaxn], deg[mmaxn];

int encode(int x, int y) {
    return x * n + y;
}

void init() {
    scanf("%d%d", &n, &m);
    irp(i, 0, n) {
        scanf("%s", tb[i]);
        for (int j = 0; tb[i][j]; j++) {
            switch (tb[i][j]) {
                case 'D':
                    tb[i][j] = 0;
                    break;
                case 'I':
                    tb[i][j] = 1;
                    break;
                case 'M':
                    tb[i][j] = 2;
                    break;
                case 'A':
                    tb[i][j] = 3;
                    break;
            }
        }
    }
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            int nx, ny;
            irp(k, 0, 4) {
                nx = x + dx[k];
                ny = y + dy[k];
                if (nx >= 0 && nx < n && ny >= 0 && ny < m) {
                    if ((tb[x][y] + 1) % 4 == tb[nx][ny]) {
                        edge[cd].push_back(encode(nx, ny));
                        deg[encode(nx, ny)]++;
                    }
                }
            }
        }
    }
}

int dfs(int u) {
    vis[u] = -1;
    for (int x:edge[u]) {
        if (vis[x] == -1) {
            return 1;
        }
        else if (vis[x] == 0) {
            if (dfs(x)) {
                return 1;
            }
        }
    }
    vis[u] = 1;
    return 0;
}

int dfs2(int u) {
    vis[u] = 1;
    int ans = 0;
    for (int x:edge[u]) {
        if (vis[x] == 0) {
            ans = max(ans, dfs2(x));
        }
        else if (vis[x] == 1) {
            ans = max(ans, deg[x]);
        }
    }
    return deg[u] = ans + 1;
}

int main() {
//    freopen("input.txt", "r", stdin);
    init();
    memc(vis, 0);
    memc(deg, 0);
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            if (vis[cd] == 0 && tb[x][y] == 0 && dfs(cd) == 1) {
                printf("Poor Inna!");
                return 0;
            }
        }
    }
    memc(vis, 0);
    int ans = 0;
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            if (vis[cd] == 0 && tb[x][y] == 0) {
                ans = max(ans, dfs2(cd));
            }
        }
    }
    if (ans < 4) {
        printf("Poor Dima!");
        return 0;
    }
    printf("%d", ans / 4);
    return 0;
}


#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <vector>

#define memc(a, x) memset(a,x,sizeof(a))
#define ll long long
#define irp(i, a, b) for(int i=a;i<b;i++)
#define drp(i, a, b) for(int i=a;i>b;i--)
#define CK cout<<'#'<<endl
#define CK2(a) cout<<'#'<<a<<endl

using namespace std;

const int maxn = 1009;
const int mmaxn = 1000009;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

char tb[maxn][maxn];
int id[maxn][maxn];
vector<int> edge[mmaxn];
int n, m;
int vis[mmaxn], deg[mmaxn];
bool rim;

int encode(int x, int y) {
    return x * n + y;
}

void init() {
    scanf("%d%d", &n, &m);
    irp(i, 0, n) {
        scanf("%s", tb[i]);
    }
    int cnt = 0;
    irp(i, 0, n)irp(j, 0, m)id[i][j] = ++cnt;
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = id[x][y];
            int nx, ny;
            irp(k, 0, 4) {
                nx = x + dx[k];
                ny = y + dy[k];
                if (nx >= 0 && nx < n && ny >= 0 && ny < m) {
                    if ((tb[x][y] == 'D' && tb[nx][ny] == 'I') ||
                        (tb[x][y] == 'I' && tb[nx][ny] == 'M') ||
                        (tb[x][y] == 'M' && tb[nx][ny] == 'A') ||
                        (tb[x][y] == 'A' && tb[nx][ny] == 'D')) {
                        edge[cd].push_back(id[nx][ny]);
                    }
                }
            }
        }
    }
}

bool dfs(int u) {
    vis[u] = -1;
    for (int x:edge[u]) {
        if (vis[x] == -1) {
            return true;
        }
        else if (vis[x] == 0 && dfs(x)) {
            return true;
        }
    }
    vis[u] = 1;
    return false;
}

int dfs2(int u) {
    vis[u] = -1;
    int ans = 0;
    for (int x:edge[u]) {
        if (vis[x] == 0) {
            ans = max(ans, dfs2(x));
        }
        else if (vis[x] == 1) {
            ans = max(ans, deg[x]);
        }
        else if (vis[x] == -1) {
            rim = true;
            return -1;
        }
    }
    vis[u] = 1;
    return deg[u] = ans + 1;
}

int main() {
//    freopen("input.txt", "r", stdin);
    init();
    memc(deg, 0);
    memc(vis, 0);
    int ans = 0;
    rim = false;
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = id[x][y];
            if (!rim && vis[cd] == 0 && tb[x][y] == 'D') {
                ans = max(ans, dfs2(cd));
            }
        }
    }
    if (rim) {
        printf("Poor Inna!");
        return 0;
    }
    if (ans < 4) {
        printf("Poor Dima!");
        return 0;
    }
    printf("%d", ans / 4);
    return 0;
}


#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <vector>

#define memc(a, x) memset(a,x,sizeof(a))
#define ll long long
#define irp(i, a, b) for(int i=a;i<b;i++)
#define drp(i, a, b) for(int i=a;i>b;i--)
#define CK cout<<'#'<<endl
#define CK2(a) cout<<'#'<<a<<endl

using namespace std;

const int maxn = 1009;
const int mmaxn = 1000009;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

char tb[maxn][maxn];
vector<int> edge[mmaxn];
int n, m;
int vis[mmaxn], deg[mmaxn];

int encode(int x, int y) {
    return x * n + y;
}

void init() {
    scanf("%d%d", &n, &m);
    irp(i, 0, n) {
        scanf("%s", tb[i]);
        for (int j = 0; tb[i][j]; j++) {
            switch (tb[i][j]) {
                case 'D':
                    tb[i][j] = 0;
                    break;
                case 'I':
                    tb[i][j] = 1;
                    break;
                case 'M':
                    tb[i][j] = 2;
                    break;
                case 'A':
                    tb[i][j] = 3;
                    break;
            }
        }
    }
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            int nx, ny;
            irp(k, 0, 4) {
                nx = x + dx[k];
                ny = y + dy[k];
                if (nx >= 0 && nx < n && ny >= 0 && ny < m) {
                    if ((tb[x][y] + 1) % 4 == tb[nx][ny]) {
                        edge[cd].push_back(encode(nx, ny));
//                        deg[encode(nx, ny)]++;
                    }
                }
            }
        }
    }
}

int dfs(int u) {
    vis[u] = -1;
    for (int x:edge[u]) {
        if (vis[x] == -1) {
            vis[u] = 1;
            return 1;
        }
        else if (vis[x] == 0) {
            if (dfs(x)) {
                vis[u] = 1;
                return 1;
            }
        }
    }
    vis[u] = 1;
    return 0;
}

int dfs2(int u) {
    vis[u] = 1;
    int ans = 0;
    for (int x:edge[u]) {
        if (vis[x] == 0) {
            ans = max(ans, dfs2(x));
        }
        else if (vis[x] == 1) {
            ans = max(ans, deg[x]);
        }
    }
    return deg[u] = ans + 1;
}

int main() {
//    freopen("input.txt", "r", stdin);
    init();
    memc(vis, 0);
    memc(deg, 0);
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            if (vis[cd] == 0 && tb[x][y] == 0 && dfs(cd) == 1) {
                printf("Poor Inna!");
                return 0;
            }
        }
    }
    memc(vis, 0);
    int ans = 0;
    irp(x, 0, n) {
        irp(y, 0, m) {
            int cd = encode(x, y);
            if (vis[cd] == 0 && tb[x][y] == 0) {
                ans = max(ans, dfs2(cd));
            }
        }
    }
    if (ans < 4) {
        printf("Poor Dima!");
        return 0;
    }
    printf("%d", ans / 4);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const ll OO = (ll) 1e9;

int n, m;
bool inf = false;

char g[1000][1000];
int x[1000][1000];

int dx[] = { 0, 0, 1, -1 };
int dy[] = { 1, -1, 0, 0 };

bool vaild(int i, int j) {
	return i >= 0 && i < n && j >= 0 && j < m;
}

char next(char c) {
	if (c == 'D')
		return 'I';
	if (c == 'I')
		return 'M';
	if (c == 'M')
		return 'A';
	if (c == 'A')
		return 'D';
	return 'N';
}

int solve(int i, int j ,string w) {
	if (x[i][j] == -2) {
		inf = true;
		return 0;
	}
	int ret = x[i][j];
	if (ret != -1)
		return x[i][j];
	x[i][j] = -2;
	ret = 0;
	w = w.substr(1)+g[i][j];
	for (int h = 0; h < 4; h++)
		if (vaild(i + dx[h], j + dy[h])
				&& g[i + dx[h]][j + dy[h]] == next(g[i][j])) {
			ret = max(ret, solve(i + dx[h], j + dy[h],w));
		}
	if (g[i][j] == 'A' && w == "DIMA")
		ret++;
	return x[i][j] = ret;
}

int main() {
	ios::sync_with_stdio(false);
	cin >> n >> m;
	memset(x, -1, sizeof x);
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)
			cin >> g[i][j];
	int res = 0;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)if(x[i][j] == -1 && g[i][j] == 'D')
			res = max(res,solve(i,j,"NNNN"));
	if(inf) cout << "Poor Inna!";
	else if(res == 0) cout << "Poor Dima!";
	else cout << res;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const ll OO = (ll) 1e9;

int n, m;
bool inf = false;

char g[1000][1000];
int x[1000][1000];

int dx[] = { 0, 0, 1, -1 };
int dy[] = { 1, -1, 0, 0 };

bool vaild(int i, int j) {
	return i >= 0 && i < n && j >= 0 && j < m;
}

char next(char c) {
	if (c == 'D')
		return 'I';
	if (c == 'I')
		return 'M';
	if (c == 'M')
		return 'A';
	if (c == 'A')
		return 'D';
	return 'N';
}

int solve(int i, int j ,char l) {
	if (x[i][j] == -2) {
		inf = true;
		return 0;
	}
	int ret = x[i][j];
	if (ret != -1)
		return x[i][j];
	x[i][j] = -2;
	ret = 0;
	for (int h = 0; h < 4; h++)
		if (vaild(i + dx[h], j + dy[h])
				&& g[i + dx[h]][j + dy[h]] == next(g[i][j])) {
			ret = max(ret, solve(i + dx[h], j + dy[h],g[i][j]));
		}
	if (g[i][j] == 'A' && l == 'M')
		ret++;
	return x[i][j] = ret;
}

int main() {
	ios::sync_with_stdio(false);
	cin >> n >> m;
	memset(x, -1, sizeof x);
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)
			cin >> g[i][j];
	int res = 0;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)if(x[i][j] == -1)
			res = max(res,solve(i,j,'N'));
	if(inf) cout << "Poor Inna!";
	else if(res == 0) cout << "Poor Dima!";
	else cout << res;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const ll OO = (ll) 1e9;

int n, m;
bool inf = false;

char g[1000][1000];
int x[1000][1000];

int dx[] = { 0, 0, 1, -1 };
int dy[] = { 1, -1, 0, 0 };

bool vaild(int i, int j) {
	return i >= 0 && i < n && j >= 0 && j < m;
}

char next(char c) {
	if (c == 'D')
		return 'I';
	if (c == 'I')
		return 'M';
	if (c == 'M')
		return 'A';
	if (c == 'A')
		return 'D';
	return 'N';
}

int solve(int i, int j) {
	if (x[i][j] == -2) {
		inf = true;
		return 0;
	}
	int ret = x[i][j];
	if (ret != -1)
		return x[i][j];
	x[i][j] = -2;
	ret = 0;
	for (int h = 0; h < 4; h++)
		if (vaild(i + dx[h], j + dy[h])
				&& g[i + dx[h]][j + dy[h]] == next(g[i][j])) {
			ret = max(ret, solve(i + dx[h], j + dy[h]));
		}
	if (g[i][j] == 'A')
		ret++;
	return x[i][j] = ret;
}

int main() {
	ios::sync_with_stdio(false);
	cin >> n >> m;
	memset(x, -1, sizeof x);
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)
			cin >> g[i][j];
	int res = 0;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)if(x[i][j] == -1)
			res = max(res,solve(i,j));
	if(inf) cout << "Poor Inna!";
	else if(res == 0) cout << "Poor Dima!";
	else cout << res;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const ll OO = (ll) 1e9;

int n, m;
bool inf = false;

char g[1000][1000];
int x[1000][1000];

int dx[] = { 0, 0, 1, -1 };
int dy[] = { 1, -1, 0, 0 };

bool vaild(int i, int j) {
	return i >= 0 && i < n && j >= 0 && j < m;
}

char next(char c) {
	if (c == 'D')
		return 'I';
	if (c == 'I')
		return 'M';
	if (c == 'M')
		return 'A';
	if (c == 'A')
		return 'D';
	return 'N';
}

int solve(int i, int j ,char l) {
	if (x[i][j] == -2) {
		inf = true;
		return 0;
	}
	int ret = x[i][j];
	if (ret != -1)
		return x[i][j];
	x[i][j] = -2;
	ret = 0;
	for (int h = 0; h < 4; h++)
		if (vaild(i + dx[h], j + dy[h])
				&& g[i + dx[h]][j + dy[h]] == next(g[i][j])) {
			ret = max(ret, solve(i + dx[h], j + dy[h],g[i][j]));
		}
	if (g[i][j] == 'A' && l == 'I')
		ret++;
	return x[i][j] = ret;
}

int main() {
	ios::sync_with_stdio(false);
	cin >> n >> m;
	memset(x, -1, sizeof x);
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)
			cin >> g[i][j];
	int res = 0;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)if(x[i][j] == -1)
			res = max(res,solve(i,j,'N'));
	if(inf) cout << "Poor Inna!";
	else if(res == 0) cout << "Poor Dima!";
	else cout << res;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const ll OO = (ll) 1e9;

int n, m;
bool inf = false;

char g[1000][1000];
int x[1000][1000];

int dx[] = { 0, 0, 1, -1 };
int dy[] = { 1, -1, 0, 0 };

bool vaild(int i, int j) {
	return i >= 0 && i < n && j >= 0 && j < m;
}

char next(char c) {
	if (c == 'D')
		return 'I';
	if (c == 'I')
		return 'M';
	if (c == 'M')
		return 'A';
	if (c == 'A')
		return 'D';
	return 'N';
}

int solve(int i, int j ,string w) {
	if (x[i][j] == -2) {
		inf = true;
		return 0;
	}
	int ret = x[i][j];
	if (ret != -1)
		return x[i][j];
	x[i][j] = -2;
	ret = 0;
	w = w.substr(1)+g[i][j];
	for (int h = 0; h < 4; h++)
		if (vaild(i + dx[h], j + dy[h])
				&& g[i + dx[h]][j + dy[h]] == next(g[i][j])) {
			ret = max(ret, solve(i + dx[h], j + dy[h],w));
		}
	if (g[i][j] == 'A' && w == "DIMA")
		ret++;
	return x[i][j] = ret;
}

int main() {
	ios::sync_with_stdio(false);
	cin >> n >> m;
	memset(x, -1, sizeof x);
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)
			cin >> g[i][j];
	int res = 0;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)if(x[i][j] == -1)
			res = max(res,solve(i,j,"NNNN"));
	if(inf) cout << "Poor Inna!";
	else if(res == 0) cout << "Poor Dima!";
	else cout << res;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int dx[]={0,0,1,-1};
const int dy[]={1,-1,0,0};
const int INF=0x3f3f3f3f;
const int MAXN=1e3+10;
string s[MAXN];
int vis[MAXN][MAXN];
map<char,char> mp;
int f[MAXN][MAXN];
int n,m,ans;
bool flag=0;
int dfs(int x,int y){
	//cout<<x<<" "<<y<<endl;
	if(ans==INF) return INF;
	if(f[x][y]!=-1) return f[x][y];
	if(vis[x][y]&&s[x][y]=='D'){
		ans=INF;
		flag=1;
		return INF;
	}
	vis[x][y]=1;
	int sum=-INF;
	for(int i=0;i<=3;i++){
		int tx=x+dx[i];
		int ty=y+dy[i];
		if(tx<=0||ty<=0||tx>n||ty>m) continue;
		if(vis[tx][ty]&&s[tx][ty]!='D') continue;
		if(mp[s[x][y]]!=s[tx][ty]) continue;
		sum=max(dfs(tx,ty),sum);
		vis[tx][ty]=0;
	}
	if(sum==-INF) sum=0;
	return f[x][y]=sum+1;
}
int main(){
	mp['D']='I';mp['I']='M';mp['M']='A';mp['A']='D';
	memset(f,-1,sizeof f);
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>s[i];
		s[i]=" "+s[i];
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(s[i][j]!='D') continue;
			flag=0;
			ans=max(dfs(i,j),ans);
			//cout<<ans<<" "<<i<<" "<<j<<endl;
			vis[i][j]=0;
		}
	}
	if(ans>=INF)cout<<"Poor Inna!\n";
	else{
		ans/=4;
		if(ans==0)cout<<"Poor Dima!\n";
		else cout<<ans<<endl;
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int dx[]={0,0,1,-1};
const int dy[]={1,-1,0,0};
const int INF=0x3f3f3f3f;
const int MAXN=1e3+10;
string s[MAXN];
int vis[MAXN][MAXN];
map<char,char> mp;
int f[MAXN][MAXN];
int n,m,ans;
bool flag=0;
int dfs(int x,int y){
	//cout<<x<<" "<<y<<endl;
	if(ans==INF) return INF;
	if(f[x][y]!=-1) return f[x][y];
	if(vis[x][y]&&s[x][y]=='D'){
		ans=INF;
		flag=1;
		return INF;
	}
	vis[x][y]=1;
	int sum=-INF;
	for(int i=0;i<=3;i++){
		int tx=x+dx[i];
		int ty=y+dy[i];
		if(tx<=0||ty<=0||tx>n||ty>m) continue;
		if(vis[tx][ty]&&s[tx][ty]!='D') continue;
		if(mp[s[x][y]]!=s[tx][ty]) continue;
		sum=max(dfs(tx,ty),sum);
		vis[tx][ty]=0;
	}
	if(sum==-INF) sum=0;
	return f[x][y]=sum+1;
}
int main(){
	mp['D']='I';mp['I']='M';mp['M']='A';mp['A']='D';
	memset(f,-1,sizeof f);
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>s[i];
		s[i]=" "+s[i];
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(s[i][j]!='D') continue;
			flag=0;
			ans=max(dfs(i,j),ans);
			//cout<<ans<<" "<<i<<" "<<j<<endl;
			vis[i][j]=0;
		}
	}
	if(ans==INF)cout<<"Poor Inna!\n";
	else{
		ans/=4;
		if(ans==0)cout<<"Poor Dima!\n";
		else cout<<ans<<endl;
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int dx[]={0,0,1,-1};
const int dy[]={1,-1,0,0};
const int INF=0x3f3f3f3f;
const int MAXN=1e3+10;
string s[MAXN];
int vis[MAXN][MAXN];
map<char,char> mp;
int n,m,ans;
bool flag=0;
void dfs(int x,int y,int sum){
	ans=max(ans,sum);/*
	cout<<x<<" "<<y<<endl;
	for(int I=1;I<=n;I++){
		for(int J=1;J<=m;J++){
			cout<<vis[I][J]<<" ";
		}
		cout<<endl;
	}
	cout<<endl;*/
	if(flag) return;
	if(vis[x][y]&&s[x][y]=='D'){
		ans=INF;
		flag=1;
		return;
	}
	vis[x][y]=1;
	for(int i=0;i<=3;i++){
		int tx=x+dx[i];
		int ty=y+dy[i];
		if(tx<=0||ty<=0||tx>n||ty>m) continue;
		if(vis[tx][ty]&&s[tx][ty]!='D') continue;
		if(mp[s[x][y]]!=s[tx][ty]) continue;
		int A=0;
		if(s[tx][ty]=='A') A=1;
		dfs(tx,ty,sum+A);
		vis[tx][ty]=0;
	}
}
int main(){
	mp['D']='I';mp['I']='M';mp['M']='A';mp['A']='D';
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>s[i];
		s[i]=" "+s[i];
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(s[i][j]!='D') continue;
			flag=0;
			dfs(i,j,0);
			vis[i][j]=0;
			//cout<<ans<<endl;
		}
	}
	if(ans==0)cout<<"Poor Dima!\n";
	else if(ans==INF)cout<<"Poor Inna!\n";
	else cout<<ans<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int dx[]={0,0,1,-1};
const int dy[]={1,-1,0,0};
const int INF=0x3f3f3f3f;
const int MAXN=1e3+10;
string s[MAXN];
int vis[MAXN][MAXN];
map<char,char> mp;
int n,m;
int sum,ans;
bool flag=0;
void dfs(int x,int y){
	cout<<x<<" "<<y<<endl;
	for(int I=1;I<=n;I++){
		for(int J=1;J<=m;J++){
			cout<<vis[I][J]<<" ";
		}
		cout<<endl;
	}
	cout<<endl;
	if(flag) return;
	if(vis[x][y]&&s[x][y]=='D'){
		sum=INF;
		flag=1;
		return;
	}
	vis[x][y]=1;
	if(s[x][y]=='A') sum++;
	for(int i=0;i<=3;i++){
		int tx=x+dx[i];
		int ty=y+dy[i];
		if(tx<=0||ty<=0||tx>n||ty>m) continue;
		if(vis[tx][ty]&&s[tx][ty]!='D') continue;
		if(mp[s[x][y]]!=s[tx][ty]) continue;
		dfs(tx,ty);
		vis[x][y]=0;
	}
}
int main(){
	mp['D']='I';mp['I']='M';mp['M']='A';mp['A']='D';
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>s[i];
		s[i]=" "+s[i];
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(s[i][j]!='D') continue;
			sum=0;
			flag=0;
			dfs(i,j);
			ans=max(sum,ans);
		}
	}
	if(ans==0)cout<<"Poor Dima!\n";
	else if(ans==INF)cout<<"Poor Inna!\n";
	else cout<<ans<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int dx[]={0,0,1,-1};
const int dy[]={1,-1,0,0};
const int INF=0x3f3f3f3f;
const int MAXN=1e3+10;
string s[MAXN];
int vis[MAXN][MAXN];
map<char,char> mp;
int f[MAXN][MAXN];
int n,m,ans;
int dfs(int x,int y){
	//cout<<x<<" "<<y<<endl;
	if(ans==INF) return INF;
	if(f[x][y]!=-1) return f[x][y];/*
	if(vis[x][y]&&s[x][y]=='D'){
		ans=INF;
		flag=1;
		return INF;
	}
	vis[x][y]=1;*/
	f[x][y]=INF;
	int sum=0;
	for(int i=0;i<=3;i++){
		int tx=x+dx[i];
		int ty=y+dy[i];
		if(tx<=0||ty<=0||tx>n||ty>m) continue;
		//if(vis[tx][ty]&&s[tx][ty]!='D') continue;
		if(mp[s[x][y]]!=s[tx][ty]) continue;
		sum=max(dfs(tx,ty),sum);
		//vis[tx][ty]=0;
	}
	return f[x][y]=min(sum+1,INF);
}
int main(){
	mp['D']='I';mp['I']='M';mp['M']='A';mp['A']='D';
	memset(f,-1,sizeof f);
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>s[i];
		s[i]=" "+s[i];
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(s[i][j]!='D') continue;
			ans=max(dfs(i,j),ans);
			//cout<<ans<<" "<<i<<" "<<j<<endl;
			vis[i][j]=0;
		}
	}
	if(ans==INF)cout<<"Poor Inna!\n";
	else{
		ans/=4;
		if(ans==0)cout<<"Poor Dima!\n";
		else cout<<ans<<endl;
	}
	return 0;
}


//====================================
//======================================
//
//                   Bismillahir-Rahmanir-Rahim
//
// ==========================================================================
#include <bits/stdc++.h>
#define        ll                              long long int
#define        FOR(x,y,z)                      for(int x=y;x<z;x++)
#define        pii                             pair<int,int>
#define        pll                             pair<ll,ll>
#define        CLR(a)                          memset(a,0,sizeof(a))
#define        SET(a)                          memset(a,-1,sizeof(a))
#define        N                               200010
#define        M                               1000000007
#define        pi                              acos(-1.0)
#define        ff                              first
#define        ss                              second
#define        pb                              push_back
#define        inf                              (1e9)+1000
#define        eps                             1e-9
#define        ALL(x)                          x.begin(),x.end()
using namespace std;
int dx[]={0,0,1,-1,-1,-1,1,1};
int dy[]={1,-1,0,0,-1,1,1,-1};
template < class T> inline T biton(T n,T pos){return n |((T)1<<pos);}
template < class T> inline T bitoff(T n,T pos){return n & ~((T)1<<pos);}
template < class T> inline T ison(T n,T pos){return (bool)(n & ((T)1<<pos));}
template < class T> inline T gcd(T a, T b){while(b){a%=b;swap(a,b);}return a;}
template <typename T> string NumberToString ( T Number ) { ostringstream ss; ss << Number; return ss.str(); }
inline int nxt(){int aaa;scanf("%d",&aaa);return aaa;}
inline ll lxt(){ll aaa;scanf("%lld",&aaa);return aaa;}
inline double dxt(){double aaa;scanf("%lf",&aaa);return aaa;}
template <class T> inline T bigmod(T p,T e,T m){T ret = 1;
for(; e > 0; e >>= 1){
    if(e & 1) ret = (ret * p) % m;p = (p * p) % m;
} return (T)ret;}
#ifdef sayed
     #define debug(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template < typename Arg1 >
    void __f(const char* name, Arg1&& arg1){
        cerr << name << " is " << arg1 << std::endl;
    }
    template < typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names+1, ',');
        cerr.write(names, comma - names) << " is " << arg1 <<endl;
        __f(comma+1, args...);
    }
#else
    #define debug(...)
#endif
///******************************************START******************************************
int ar[N];
int n,m;
bool cycle = 0;
char s[1003][1003];
string t = "DIMA";
int dp[1003][1003][4];
int vis[1003][1003][4];
int now = 1;
int dfs(int i,int j,int khuj){
    if(cycle) return 0;
    if(vis[i][j][khuj]==now-5) return dp[i][j][khuj];
    vis[i][j][khuj] = now;
    int res = 0;
    for(int k = 0;k<4;k++) {
        int nx = i+dx[k];
        int ny = j+dy[k];
        if(nx<0||nx>=n||ny<0||ny>=m) continue;
        int nkhuj = khuj+1;
        if(nkhuj==4) nkhuj = 0;
        if(s[nx][ny]!=t[nkhuj]) continue;
        if(vis[nx][ny][nkhuj]==now){
            cycle = true;
            return 0;
        }

            res = max(res,dfs(nx,ny,nkhuj)+1);
    }
    vis[i][j][khuj] = now-5;
    return dp[i][j][khuj]=res;
}
int main(){
    #ifdef sayed
    //freopen("out.txt","w",stdout);
    // freopen("in.txt","r",stdin);
    #endif
    //ios_base::sync_with_stdio(false);
    //cin.tie(0);
    n = nxt();
    m =nxt();
    for(int i = 0;i<n;i++) scanf("%s",s[i]);
    int res = 0;
    SET(dp);
    for(int i = 0;i<n;i++) {
        for(int j = 0;j<m;j++) {
            if(s[i][j]=='D') {
                now++;
                if(vis[i][j][0]==0)
                    res = max(res,dfs(i,j,0)+1);
            }
            if(cycle){
                //debug(i,j);
                printf("Poor Inna!\n");
                return 0;
            }
        }
    }
    res/=4;
    if(res) printf("%d\n",res);
    else printf("Poor Dima!\n");

    return 0;
}


//====================================
//======================================
//
//                   Bismillahir-Rahmanir-Rahim
//
// ==========================================================================
#include <bits/stdc++.h>
#define        ll                              long long int
#define        FOR(x,y,z)                      for(int x=y;x<z;x++)
#define        pii                             pair<int,int>
#define        pll                             pair<ll,ll>
#define        CLR(a)                          memset(a,0,sizeof(a))
#define        SET(a)                          memset(a,-1,sizeof(a))
#define        N                               200010
#define        M                               1000000007
#define        pi                              acos(-1.0)
#define        ff                              first
#define        ss                              second
#define        pb                              push_back
#define        inf                              (1e9)+1000
#define        eps                             1e-9
#define        ALL(x)                          x.begin(),x.end()
using namespace std;
int dx[]={0,0,1,-1,-1,-1,1,1};
int dy[]={1,-1,0,0,-1,1,1,-1};
template < class T> inline T biton(T n,T pos){return n |((T)1<<pos);}
template < class T> inline T bitoff(T n,T pos){return n & ~((T)1<<pos);}
template < class T> inline T ison(T n,T pos){return (bool)(n & ((T)1<<pos));}
template < class T> inline T gcd(T a, T b){while(b){a%=b;swap(a,b);}return a;}
template <typename T> string NumberToString ( T Number ) { ostringstream ss; ss << Number; return ss.str(); }
inline int nxt(){int aaa;scanf("%d",&aaa);return aaa;}
inline ll lxt(){ll aaa;scanf("%lld",&aaa);return aaa;}
inline double dxt(){double aaa;scanf("%lf",&aaa);return aaa;}
template <class T> inline T bigmod(T p,T e,T m){T ret = 1;
for(; e > 0; e >>= 1){
    if(e & 1) ret = (ret * p) % m;p = (p * p) % m;
} return (T)ret;}
#ifdef sayed
     #define debug(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template < typename Arg1 >
    void __f(const char* name, Arg1&& arg1){
        cerr << name << " is " << arg1 << std::endl;
    }
    template < typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names+1, ',');
        cerr.write(names, comma - names) << " is " << arg1 <<endl;
        __f(comma+1, args...);
    }
#else
    #define debug(...)
#endif
///******************************************START******************************************
int ar[N];
int n,m;
bool cycle = 0;
char s[1003][1003];
string t = "DIMA";
int dp[1003][1003][4];
int vis[1003][1003][4];
int now = 1;
int dfs(int i,int j,int khuj){
    if(cycle) return 0;
    if(vis[i][j][khuj]==now-5) return dp[i][j][khuj];
    vis[i][j][khuj] = now;
    int res = 0;
    for(int k = 0;k<4;k++) {
        int nx = i+dx[k];
        int ny = j+dy[k];
        if(nx<0||nx>=n||ny<0||ny>=m) continue;
        int nkhuj = khuj+1;
        if(nkhuj==4) nkhuj = 0;
        if(s[nx][ny]!=t[nkhuj]) continue;
        if(vis[nx][ny][nkhuj]==now){
            cycle = true;
            return 0;
        }
        res = max(res,dfs(nx,ny,nkhuj)+1);
    }
    vis[i][j][khuj] = now-5;
    return dp[i][j][khuj]=res;
}
int main(){
    #ifdef sayed
    //freopen("out.txt","w",stdout);
    // freopen("in.txt","r",stdin);
    #endif
    //ios_base::sync_with_stdio(false);
    //cin.tie(0);
    n = nxt();
    m =nxt();
    for(int i = 0;i<n;i++) scanf("%s",s[i]);
    int res = 0;
    SET(dp);
    for(int i = 0;i<n;i++) {
        for(int j = 0;j<m;j++) {
            if(s[i][j]=='D') {
                now++;
               // debug(i,j);
                res = max(res,dfs(i,j,0)+1);
            }
            if(cycle){
                //debug(i,j);
                printf("Poor Inna!\n");
                return 0;
            }
        }
    }
    res/=4;
    if(res) printf("%d\n",res);
    else printf("Poor Dima!\n");

    return 0;
}


//====================================
//======================================
//
//                   Bismillahir-Rahmanir-Rahim
//
// ==========================================================================
#include <bits/stdc++.h>
#define        ll                              long long int
#define        FOR(x,y,z)                      for(int x=y;x<z;x++)
#define        pii                             pair<int,int>
#define        pll                             pair<ll,ll>
#define        CLR(a)                          memset(a,0,sizeof(a))
#define        SET(a)                          memset(a,-1,sizeof(a))
#define        N                               200010
#define        M                               1000000007
#define        pi                              acos(-1.0)
#define        ff                              first
#define        ss                              second
#define        pb                              push_back
#define        inf                              (1e9)+1000
#define        eps                             1e-9
#define        ALL(x)                          x.begin(),x.end()
using namespace std;
int dx[]={0,0,1,-1,-1,-1,1,1};
int dy[]={1,-1,0,0,-1,1,1,-1};
template < class T> inline T biton(T n,T pos){return n |((T)1<<pos);}
template < class T> inline T bitoff(T n,T pos){return n & ~((T)1<<pos);}
template < class T> inline T ison(T n,T pos){return (bool)(n & ((T)1<<pos));}
template < class T> inline T gcd(T a, T b){while(b){a%=b;swap(a,b);}return a;}
template <typename T> string NumberToString ( T Number ) { ostringstream ss; ss << Number; return ss.str(); }
inline int nxt(){int aaa;scanf("%d",&aaa);return aaa;}
inline ll lxt(){ll aaa;scanf("%lld",&aaa);return aaa;}
inline double dxt(){double aaa;scanf("%lf",&aaa);return aaa;}
template <class T> inline T bigmod(T p,T e,T m){T ret = 1;
for(; e > 0; e >>= 1){
    if(e & 1) ret = (ret * p) % m;p = (p * p) % m;
} return (T)ret;}
#ifdef sayed
     #define debug(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template < typename Arg1 >
    void __f(const char* name, Arg1&& arg1){
        cerr << name << " is " << arg1 << std::endl;
    }
    template < typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names+1, ',');
        cerr.write(names, comma - names) << " is " << arg1 <<endl;
        __f(comma+1, args...);
    }
#else
    #define debug(...)
#endif
///******************************************START******************************************
int ar[N];
int n,m;
bool cycle = 0;
char s[1003][1003];
string t = "DIMA";
int dp[1003][1003][4];
int vis[1003][1003][4];
int now = 1;
int dfs(int i,int j,int khuj){
  // debug(i,j,khuj);
    if(cycle) return 0;
    if(dp[i][j][khuj]!=-1) return dp[i][j][khuj];
    vis[i][j][khuj] = now;
    int res = 0;
    for(int k = 0;k<4;k++) {
        int nx = i+dx[k];
        int ny = j+dy[k];
        if(nx<0||nx>=n||ny<0||ny>=m) continue;
        int nkhuj = khuj+1;
        if(nkhuj==4) nkhuj = 0;
        if(s[nx][ny]!=t[nkhuj]) continue;
        if(vis[nx][ny][nkhuj]==now&&nkhuj==0){
            cycle = true;
            return 0;
        }

        res = max(res,dfs(nx,ny,nkhuj)+1);
    }
    vis[i][j][khuj] = now-5;
    return dp[i][j][khuj]=res;
}
int main(){
    #ifdef sayed
    //freopen("out.txt","w",stdout);
    // freopen("in.txt","r",stdin);
    #endif
    //ios_base::sync_with_stdio(false);
    //cin.tie(0);
    n = nxt();
    m =nxt();
    for(int i = 0;i<n;i++) scanf("%s",s[i]);
    int res = 0;
    SET(dp);
    for(int i = 0;i<n;i++) {
        for(int j = 0;j<m;j++) {
            if(s[i][j]=='D') {
                now++;
               // debug(i,j);
                res = max(res,dfs(i,j,0)+1);
            }
            if(cycle){
                //debug(i,j);
                printf("Poor Inna!\n");
                return 0;
            }
        }
    }
    res/=4;
    if(res) printf("%d\n",res);
    else printf("Poor Dima!\n");

    return 0;
}


//====================================
//======================================
//
//                   Bismillahir-Rahmanir-Rahim
//
// ==========================================================================
#include <bits/stdc++.h>
#define        ll                              long long int
#define        FOR(x,y,z)                      for(int x=y;x<z;x++)
#define        pii                             pair<int,int>
#define        pll                             pair<ll,ll>
#define        CLR(a)                          memset(a,0,sizeof(a))
#define        SET(a)                          memset(a,-1,sizeof(a))
#define        N                               200010
#define        M                               1000000007
#define        pi                              acos(-1.0)
#define        ff                              first
#define        ss                              second
#define        pb                              push_back
#define        inf                              (1e9)+1000
#define        eps                             1e-9
#define        ALL(x)                          x.begin(),x.end()
using namespace std;
int dx[]={0,0,1,-1,-1,-1,1,1};
int dy[]={1,-1,0,0,-1,1,1,-1};
template < class T> inline T biton(T n,T pos){return n |((T)1<<pos);}
template < class T> inline T bitoff(T n,T pos){return n & ~((T)1<<pos);}
template < class T> inline T ison(T n,T pos){return (bool)(n & ((T)1<<pos));}
template < class T> inline T gcd(T a, T b){while(b){a%=b;swap(a,b);}return a;}
template <typename T> string NumberToString ( T Number ) { ostringstream ss; ss << Number; return ss.str(); }
inline int nxt(){int aaa;scanf("%d",&aaa);return aaa;}
inline ll lxt(){ll aaa;scanf("%lld",&aaa);return aaa;}
inline double dxt(){double aaa;scanf("%lf",&aaa);return aaa;}
template <class T> inline T bigmod(T p,T e,T m){T ret = 1;
for(; e > 0; e >>= 1){
    if(e & 1) ret = (ret * p) % m;p = (p * p) % m;
} return (T)ret;}
#ifdef sayed
     #define debug(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template < typename Arg1 >
    void __f(const char* name, Arg1&& arg1){
        cerr << name << " is " << arg1 << std::endl;
    }
    template < typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names+1, ',');
        cerr.write(names, comma - names) << " is " << arg1 <<endl;
        __f(comma+1, args...);
    }
#else
    #define debug(...)
#endif
///******************************************START******************************************
int ar[N];
int n,m;
bool cycle = 0;
char s[1003][1003];
string t = "DIMA";
int dp[1003][1003][4];
int vis[1003][1003][4];
int now = 1;
int dfs(int i,int j,int khuj){
  // debug(i,j,khuj);
    if(cycle) return 0;
    vis[i][j][khuj] = now;
    if(dp[i][j][khuj]!=-1) return dp[i][j][khuj];
    int res = 0;
    for(int k = 0;k<4;k++) {
        int nx = i+dx[k];
        int ny = j+dy[k];
        if(nx<0||nx>=n||ny<0||ny>=m) continue;
        int nkhuj = khuj+1;
        if(nkhuj==4) nkhuj = 0;
        if(s[nx][ny]!=t[nkhuj]) continue;
        if(vis[nx][ny][nkhuj]==now&&nkhuj==0){
            cycle = true;
            return 0;
        }
        if(vis[nx][ny][nkhuj]!=0) continue;
       // debug(nx,ny);
        res = max(res,dfs(nx,ny,nkhuj)+1);
    }
    vis[i][j][khuj] = now-5;
    return dp[i][j][khuj]=res;
}
int main(){
    #ifdef sayed
    //freopen("out.txt","w",stdout);
    // freopen("in.txt","r",stdin);
    #endif
    //ios_base::sync_with_stdio(false);
    //cin.tie(0);
    n = nxt();
    m =nxt();
    for(int i = 0;i<n;i++) scanf("%s",s[i]);
    int res = 0;
    SET(dp);
    for(int i = 0;i<n;i++) {
        for(int j = 0;j<m;j++) {
            if(s[i][j]=='D') {
                now++;
               // debug(i,j);
                res = max(res,dfs(i,j,0)+1);
            }
            if(cycle){
                //debug(i,j);
                printf("Poor Inna!\n");
                return 0;
            }
        }
    }
    res/=4;
    if(res) printf("%d\n",res);
    else printf("Poor Dima!\n");

    return 0;
}


//====================================
//======================================
//
//                   Bismillahir-Rahmanir-Rahim
//
// ==========================================================================
#include <bits/stdc++.h>
#define        ll                              long long int
#define        FOR(x,y,z)                      for(int x=y;x<z;x++)
#define        pii                             pair<int,int>
#define        pll                             pair<ll,ll>
#define        CLR(a)                          memset(a,0,sizeof(a))
#define        SET(a)                          memset(a,-1,sizeof(a))
#define        N                               200010
#define        M                               1000000007
#define        pi                              acos(-1.0)
#define        ff                              first
#define        ss                              second
#define        pb                              push_back
#define        inf                              (1e9)+1000
#define        eps                             1e-9
#define        ALL(x)                          x.begin(),x.end()
using namespace std;
int dx[]={0,0,1,-1,-1,-1,1,1};
int dy[]={1,-1,0,0,-1,1,1,-1};
template < class T> inline T biton(T n,T pos){return n |((T)1<<pos);}
template < class T> inline T bitoff(T n,T pos){return n & ~((T)1<<pos);}
template < class T> inline T ison(T n,T pos){return (bool)(n & ((T)1<<pos));}
template < class T> inline T gcd(T a, T b){while(b){a%=b;swap(a,b);}return a;}
template <typename T> string NumberToString ( T Number ) { ostringstream ss; ss << Number; return ss.str(); }
inline int nxt(){int aaa;scanf("%d",&aaa);return aaa;}
inline ll lxt(){ll aaa;scanf("%lld",&aaa);return aaa;}
inline double dxt(){double aaa;scanf("%lf",&aaa);return aaa;}
template <class T> inline T bigmod(T p,T e,T m){T ret = 1;
for(; e > 0; e >>= 1){
    if(e & 1) ret = (ret * p) % m;p = (p * p) % m;
} return (T)ret;}
#ifdef sayed
     #define debug(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template < typename Arg1 >
    void __f(const char* name, Arg1&& arg1){
        cerr << name << " is " << arg1 << std::endl;
    }
    template < typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names+1, ',');
        cerr.write(names, comma - names) << " is " << arg1 <<endl;
        __f(comma+1, args...);
    }
#else
    #define debug(...)
#endif
///******************************************START******************************************
int ar[N];
int n,m;
bool cycle = 0;
char s[1003][1003];
string t = "DIMA";
int dp[1003][1003][4];
int vis[1003][1003][4];
int now = 1;
int dfs(int i,int j,int khuj){
  // debug(i,j,khuj);
    if(cycle) return 0;
    if(dp[i][j][khuj]!=-1) return dp[i][j][khuj];
    vis[i][j][khuj] = now;
    int res = 0;
    for(int k = 0;k<4;k++) {
        int nx = i+dx[k];
        int ny = j+dy[k];
        if(nx<0||nx>=n||ny<0||ny>=m) continue;
        int nkhuj = khuj +1;
        if(nkhuj==4) nkhuj = 0;
        if(s[nx][ny]!=t[nkhuj]) continue;
        if(vis[nx][ny][nkhuj]==now&&nkhuj==0){
            cycle = true;
            return 0;
        }
       // debug(nx,ny);
        res = max(res,dfs(nx,ny,nkhuj)+1);
    }
    return dp[i][j][khuj]=res;
}
int main(){
    #ifdef sayed
    //freopen("out.txt","w",stdout);
    // freopen("in.txt","r",stdin);
    #endif
    //ios_base::sync_with_stdio(false);
    //cin.tie(0);
    n = nxt();
    m =nxt();
    for(int i = 0;i<n;i++) scanf("%s",s[i]);
    int res = 0;
    SET(dp);
    for(int i = 0;i<n;i++) {
        for(int j = 0;j<m;j++) {
            if(s[i][j]=='D') {
                now++;
               // debug(i,j);
                res = max(res,dfs(i,j,0)+1);
            }
            if(cycle){
                printf("Poor Inna!\n");
                return 0;
            }
        }
    }
    res/=4;
    if(res) printf("%d\n",res);
    else printf("Poor Dima!\n");

    return 0;
}


//====================================
//======================================
//
//                   Bismillahir-Rahmanir-Rahim
//
// ==========================================================================
#include <bits/stdc++.h>
#define        ll                              long long int
#define        FOR(x,y,z)                      for(int x=y;x<z;x++)
#define        pii                             pair<int,int>
#define        pll                             pair<ll,ll>
#define        CLR(a)                          memset(a,0,sizeof(a))
#define        SET(a)                          memset(a,-1,sizeof(a))
#define        N                               200010
#define        M                               1000000007
#define        pi                              acos(-1.0)
#define        ff                              first
#define        ss                              second
#define        pb                              push_back
#define        inf                              (1e9)+1000
#define        eps                             1e-9
#define        ALL(x)                          x.begin(),x.end()
using namespace std;
int dx[]={0,0,1,-1,-1,-1,1,1};
int dy[]={1,-1,0,0,-1,1,1,-1};
template < class T> inline T biton(T n,T pos){return n |((T)1<<pos);}
template < class T> inline T bitoff(T n,T pos){return n & ~((T)1<<pos);}
template < class T> inline T ison(T n,T pos){return (bool)(n & ((T)1<<pos));}
template < class T> inline T gcd(T a, T b){while(b){a%=b;swap(a,b);}return a;}
template <typename T> string NumberToString ( T Number ) { ostringstream ss; ss << Number; return ss.str(); }
inline int nxt(){int aaa;scanf("%d",&aaa);return aaa;}
inline ll lxt(){ll aaa;scanf("%lld",&aaa);return aaa;}
inline double dxt(){double aaa;scanf("%lf",&aaa);return aaa;}
template <class T> inline T bigmod(T p,T e,T m){T ret = 1;
for(; e > 0; e >>= 1){
    if(e & 1) ret = (ret * p) % m;p = (p * p) % m;
} return (T)ret;}
#ifdef sayed
     #define debug(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template < typename Arg1 >
    void __f(const char* name, Arg1&& arg1){
        cerr << name << " is " << arg1 << std::endl;
    }
    template < typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names+1, ',');
        cerr.write(names, comma - names) << " is " << arg1 <<endl;
        __f(comma+1, args...);
    }
#else
    #define debug(...)
#endif
///******************************************START******************************************
int ar[N];
int n,m;
bool cycle = 0;
char s[1003][1003];
string t = "DIMA";
int dp[1003][1003][4];
int vis[1003][1003][4];
int now = 1;
int dfs(int i,int j,int khuj){
    if(cycle) return 0;
    if(vis[i][j][khuj]==2) return dp[i][j][khuj];
    vis[i][j][khuj] = 1;
    int res = 0;
    for(int k = 0;k<4;k++) {
        int nx = i+dx[k];
        int ny = j+dy[k];
        if(nx<0||nx>=n||ny<0||ny>=m) continue;
        int nkhuj = khuj+1;
        if(nkhuj==4) nkhuj = 0;
        if(s[nx][ny]!=t[nkhuj]) continue;
        if(vis[nx][ny][nkhuj]==1){
            cycle = true;
            return 0;
        }

            res = max(res,dfs(nx,ny,nkhuj)+1);
    }
    vis[i][j][khuj] = 2;
    return dp[i][j][khuj]=res;
}
int main(){
    #ifdef sayed
    //freopen("out.txt","w",stdout);
    // freopen("in.txt","r",stdin);
    #endif
    //ios_base::sync_with_stdio(false);
    //cin.tie(0);
    n = nxt();
    m =nxt();
    for(int i = 0;i<n;i++) scanf("%s",s[i]);
    int res = 0;
    SET(dp);
    for(int i = 0;i<n;i++) {
        for(int j = 0;j<m;j++) {
            if(s[i][j]=='D') {
                if(vis[i][j][0]==0)
                    res = max(res,dfs(i,j,0)+1);
            }
            if(cycle){
                //debug(i,j);
                printf("Poor Inna!\n");
                return 0;
            }
        }
    }
    res/=4;
    if(res) printf("%d\n",res);
    else printf("Poor Dima!\n");

    return 0;
}


//====================================
//======================================
//
//                   Bismillahir-Rahmanir-Rahim
//
// ==========================================================================
#include <bits/stdc++.h>
#define        ll                              long long int
#define        FOR(x,y,z)                      for(int x=y;x<z;x++)
#define        pii                             pair<int,int>
#define        pll                             pair<ll,ll>
#define        CLR(a)                          memset(a,0,sizeof(a))
#define        SET(a)                          memset(a,-1,sizeof(a))
#define        N                               200010
#define        M                               1000000007
#define        pi                              acos(-1.0)
#define        ff                              first
#define        ss                              second
#define        pb                              push_back
#define        inf                              (1e9)+1000
#define        eps                             1e-9
#define        ALL(x)                          x.begin(),x.end()
using namespace std;
int dx[]={0,0,1,-1,-1,-1,1,1};
int dy[]={1,-1,0,0,-1,1,1,-1};
template < class T> inline T biton(T n,T pos){return n |((T)1<<pos);}
template < class T> inline T bitoff(T n,T pos){return n & ~((T)1<<pos);}
template < class T> inline T ison(T n,T pos){return (bool)(n & ((T)1<<pos));}
template < class T> inline T gcd(T a, T b){while(b){a%=b;swap(a,b);}return a;}
template <typename T> string NumberToString ( T Number ) { ostringstream ss; ss << Number; return ss.str(); }
inline int nxt(){int aaa;scanf("%d",&aaa);return aaa;}
inline ll lxt(){ll aaa;scanf("%lld",&aaa);return aaa;}
inline double dxt(){double aaa;scanf("%lf",&aaa);return aaa;}
template <class T> inline T bigmod(T p,T e,T m){T ret = 1;
for(; e > 0; e >>= 1){
    if(e & 1) ret = (ret * p) % m;p = (p * p) % m;
} return (T)ret;}
#ifdef sayed
     #define debug(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template < typename Arg1 >
    void __f(const char* name, Arg1&& arg1){
        cerr << name << " is " << arg1 << std::endl;
    }
    template < typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names+1, ',');
        cerr.write(names, comma - names) << " is " << arg1 <<endl;
        __f(comma+1, args...);
    }
#else
    #define debug(...)
#endif
///******************************************START******************************************
int ar[N];
int n,m;
bool cycle = 0;
char s[1003][1003];
string t = "DIMA";
int dp[1003][1003][4];
int vis[1003][1003][4];
int now = 1;
int dfs(int i,int j,int khuj){
    if(cycle) return 0;
    if(vis[i][j][khuj]==2) return dp[i][j][khuj];
    vis[i][j][khuj] = 1;
    int res = 0;
    for(int k = 0;k<4;k++) {
        int nx = i+dx[k];
        int ny = j+dy[k];
        if(nx<0||nx>=n||ny<0||ny>=m) continue;
        int nkhuj = khuj+1;
        if(nkhuj==4) nkhuj = 0;
        if(s[nx][ny]!=t[nkhuj]) continue;
        if(vis[nx][ny][nkhuj]==1){
            cycle = true;
            return 0;
        }

            res = max(res,dfs(nx,ny,nkhuj)+1);
    }
    vis[i][j][khuj] = 2;
    return dp[i][j][khuj]=res;
}
int main(){
    #ifdef sayed
    //freopen("out.txt","w",stdout);
    // freopen("in.txt","r",stdin);
    #endif
    //ios_base::sync_with_stdio(false);
    //cin.tie(0);
    n = nxt();
    m =nxt();
    for(int i = 0;i<n;i++) scanf("%s",s[i]);
    int res = 0;
    SET(dp);
    for(int i = 0;i<n;i++) {
        for(int j = 0;j<m;j++) {
            if(s[i][j]=='D') {
                    res = max(res,dfs(i,j,0)+1);
            }
            if(cycle){
                //debug(i,j);
                printf("Poor Inna!\n");
                return 0;
            }
        }
    }
    res/=4;
    if(res) printf("%d\n",res);
    else printf("Poor Dima!\n");

    return 0;
}


//====================================
//======================================
//
//                   Bismillahir-Rahmanir-Rahim
//
// ==========================================================================
#include <bits/stdc++.h>
#define        ll                              long long int
#define        FOR(x,y,z)                      for(int x=y;x<z;x++)
#define        pii                             pair<int,int>
#define        pll                             pair<ll,ll>
#define        CLR(a)                          memset(a,0,sizeof(a))
#define        SET(a)                          memset(a,-1,sizeof(a))
#define        N                               200010
#define        M                               1000000007
#define        pi                              acos(-1.0)
#define        ff                              first
#define        ss                              second
#define        pb                              push_back
#define        inf                              (1e9)+1000
#define        eps                             1e-9
#define        ALL(x)                          x.begin(),x.end()
using namespace std;
int dx[]={0,0,1,-1,-1,-1,1,1};
int dy[]={1,-1,0,0,-1,1,1,-1};
template < class T> inline T biton(T n,T pos){return n |((T)1<<pos);}
template < class T> inline T bitoff(T n,T pos){return n & ~((T)1<<pos);}
template < class T> inline T ison(T n,T pos){return (bool)(n & ((T)1<<pos));}
template < class T> inline T gcd(T a, T b){while(b){a%=b;swap(a,b);}return a;}
template <typename T> string NumberToString ( T Number ) { ostringstream ss; ss << Number; return ss.str(); }
inline int nxt(){int aaa;scanf("%d",&aaa);return aaa;}
inline ll lxt(){ll aaa;scanf("%lld",&aaa);return aaa;}
inline double dxt(){double aaa;scanf("%lf",&aaa);return aaa;}
template <class T> inline T bigmod(T p,T e,T m){T ret = 1;
for(; e > 0; e >>= 1){
    if(e & 1) ret = (ret * p) % m;p = (p * p) % m;
} return (T)ret;}
#ifdef sayed
     #define debug(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template < typename Arg1 >
    void __f(const char* name, Arg1&& arg1){
        cerr << name << " is " << arg1 << std::endl;
    }
    template < typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names+1, ',');
        cerr.write(names, comma - names) << " is " << arg1 <<endl;
        __f(comma+1, args...);
    }
#else
    #define debug(...)
#endif
///******************************************START******************************************
int ar[N];
int n,m;
bool cycle = 0;
char s[1003][1003];
string t = "DIMA";
int dp[1003][1003][4];
int vis[1003][1003][4];
int now = 1;
int dfs(int i,int j,int khuj){
  // debug(i,j,khuj);
    if(cycle) return 0;
    vis[i][j][khuj] = now;
    if(dp[i][j][khuj]!=-1) return dp[i][j][khuj];
    int res = 0;
    for(int k = 0;k<4;k++) {
        int nx = i+dx[k];
        int ny = j+dy[k];
        if(nx<0||nx>=n||ny<0||ny>=m) continue;
        int nkhuj = khuj +1;
        if(nkhuj==4) nkhuj = 0;
        if(s[nx][ny]!=t[nkhuj]) continue;
        if(vis[nx][ny][nkhuj]==now&&nkhuj==0){
            cycle = true;
            return 0;
        }
       // debug(nx,ny);
        res = max(res,dfs(nx,ny,nkhuj)+1);
    }
    vis[i][j][khuj] = now - 5;
    return dp[i][j][khuj]=res;
}
int main(){
    #ifdef sayed
    //freopen("out.txt","w",stdout);
    // freopen("in.txt","r",stdin);
    #endif
    //ios_base::sync_with_stdio(false);
    //cin.tie(0);
    n = nxt();
    m =nxt();
    for(int i = 0;i<n;i++) scanf("%s",s[i]);
    int res = 0;
    SET(dp);
    for(int i = 0;i<n;i++) {
        for(int j = 0;j<m;j++) {
            if(s[i][j]=='D') {
                now++;
               // debug(i,j);
                res = max(res,dfs(i,j,0)+1);
            }
            if(cycle){
                //debug(i,j);
                printf("Poor Inna!\n");
                return 0;
            }
        }
    }
    res/=4;
    if(res) printf("%d\n",res);
    else printf("Poor Dima!\n");

    return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define pil pair<int,ll>
#define fi first
#define se second
#define inf (INT_MAX/2-1)
#define infl (1LL<<60)
#define vi vector<int>
#define vl vector<ll>
#define pb push_back
#define sz(a) (int)(a).size()
#define all(a) begin(a),end(a)
#define y0 y5656
#define y1 y7878
#define y2 y9090
#define aaa system("pause");
#define dbg(x) cerr<<(#x)<<": "<<(x)<<'\n',aaa
#define dbga(x,n) cerr<<(#x)<<"[]: ";for(int _=0;_<n;_++)cerr<<x[_]<<' ';cerr<<'\n',aaa
#define dbgs(x) cerr<<(#x)<<"[stl]: ";for(auto _:x)cerr<<_<<' ';cerr<<'\n',aaa
#define dbgp(x) cerr<<(#x)<<": "<<x.fi<<' '<<x.se<<'\n',aaa
#define maxn 1000

using namespace std;

const int dim = maxn*(maxn+3)+5;
int v[maxn+5][maxn+5], dist[dim], grad[dim], dx[4] = {-1, 0, 1, 0}, dy[4] = {0, -1, 0, 1};
bool viz[dim];
vi g[dim], gt[dim];

void umax(int &a, int b) { a = max(a, b); }
int id (int x, int y) { return x*(maxn+2)+y; }
int tip (int x) {
  int i = x/(maxn+2), j = x%(maxn+2);
  return v[i][j];
}

void df (int nod) {
  if (viz[nod] && tip(nod) == 1) {
    cout << "Poor Inna!\n";
    exit(0);
  }
  viz[nod] = 1;
  for (int nn: g[nod]) df(nn);
}

int main () {
  ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
  int n, m; cin >> n >> m;
  int i, j, z;
  string s;
  for (i = 1; i <= n; i++) {
    cin >> s;
    s = " " + s;
    for (j = 1; j <= m; j++) {
      if (s[j] == 'D') v[i][j] = 1;
      if (s[j] == 'I') v[i][j] = 2;
      if (s[j] == 'M') v[i][j] = 3;
      if (s[j] == 'A') v[i][j] = 4;
    }
  }
  int x, y;
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++)
      for (z = 0; z < 4; z++) {
        x = i + dx[z]; y = j + dy[z];
        if (v[i][j]%4+1 == v[x][y]) {
          g[id(i,j)].pb(id(x,y));
          gt[id(x,y)].pb(id(i,j));
        }
      }
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++)
      if (v[i][j] == 1 && !viz[id(i,j)]) df(id(i,j));
  queue<int> qu;
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++) {
      z = id(i, j);
      grad[z] = sz(gt[z]);
      if (grad[z] == 0) qu.push(z);
    }
  fill(all(dist), -inf);
  int ans = -inf;
  while (!qu.empty()) {
    int x = qu.front(); qu.pop();
    for (int nn: gt[x]) umax(dist[x], dist[nn]+1);
    if (tip(x) == 1) umax(dist[x], 1);
    umax(ans, dist[x]);
    for (int nn: g[x]) {
      grad[nn]--;
      if (grad[nn] == 0) qu.push(nn);
    }
  }
  if (ans < 4) cout << "Poor Dima!\n";
  else cout << ans/4;
  return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define pil pair<int,ll>
#define fi first
#define se second
#define inf (INT_MAX/2-1)
#define infl (1LL<<60)
#define vi vector<int>
#define vl vector<ll>
#define pb push_back
#define sz(a) (int)(a).size()
#define all(a) begin(a),end(a)
#define y0 y5656
#define y1 y7878
#define y2 y9090
#define aaa system("pause");
#define dbg(x) cerr<<(#x)<<": "<<(x)<<'\n',aaa
#define dbga(x,n) cerr<<(#x)<<"[]: ";for(int _=0;_<n;_++)cerr<<x[_]<<' ';cerr<<'\n',aaa
#define dbgs(x) cerr<<(#x)<<"[stl]: ";for(auto _:x)cerr<<_<<' ';cerr<<'\n',aaa
#define dbgp(x) cerr<<(#x)<<": "<<x.fi<<' '<<x.se<<'\n',aaa
#define maxn 1000

using namespace std;

const int dim = maxn*(maxn+3)+5;
int v[maxn+5][maxn+5], dist[dim], grad[dim], dx[4] = {-1, 0, 1, 0}, dy[4] = {0, -1, 0, 1};
bool viz[dim];
vi g[dim], gt[dim];

void umax(int &a, int b) { a = max(a, b); }
int id (int x, int y) { return x*(maxn+2)+y; }

void ciclu () {
  cout << "Poor Inna!\n";
  exit(0);
}

int tip (int x) {
  int i = x/(maxn+2), j = x%(maxn+2);
  return v[i][j];
}

void dag (int nod) {
  if (viz[nod]) ciclu();
  viz[nod] = 1;
  for (int nn: g[nod]) dag(nn);
  viz[nod] = 0;
}

int main () {
  ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
  int n, m; cin >> n >> m;
  int i, j, z;
  string s;
  for (i = 1; i <= n; i++) {
    cin >> s;
    s = " " + s;
    for (j = 1; j <= m; j++) {
      if (s[j] == 'D') v[i][j] = 1;
      if (s[j] == 'I') v[i][j] = 2;
      if (s[j] == 'M') v[i][j] = 3;
      if (s[j] == 'A') v[i][j] = 4;
    }
  }
  int x, y, p = 0;///p = nr muchii
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++)
      for (z = 0; z < 4; z++) {
        x = i + dx[z]; y = j + dy[z];
        if (v[i][j]%4+1 == v[x][y]) {
          g[id(i,j)].pb(id(x,y));
          gt[id(x,y)].pb(id(i,j));
          p++;
        }
      }
  bool in = 0;
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++)
      if (sz(gt[id(i,j)]) == 0 && sz(g[id(i,j)]) > 0) {
        dag(id(i,j));
        in = 1;
      }
  if (!in && p > 0) ciclu();
  queue<int> qu;
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++) {
      z = id(i, j);
      grad[z] = sz(gt[z]);
      if (grad[z] == 0) qu.push(z);
    }
  fill(all(dist), -inf);
  int ans = -inf;
  while (!qu.empty()) {
    int x = qu.front(); qu.pop();
    for (int nn: gt[x]) umax(dist[x], dist[nn]+1);
    if (tip(x) == 1) umax(dist[x], 1);
    umax(ans, dist[x]);
    for (int nn: g[x]) {
      grad[nn]--;
      if (grad[nn] == 0) qu.push(nn);
    }
  }
  if (ans < 4) cout << "Poor Dima!\n";
  else cout << ans/4;
  return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define pil pair<int,ll>
#define fi first
#define se second
#define inf (INT_MAX/2-1)
#define infl (1LL<<60)
#define vi vector<int>
#define vl vector<ll>
#define pb push_back
#define sz(a) (int)(a).size()
#define all(a) begin(a),end(a)
#define y0 y5656
#define y1 y7878
#define y2 y9090
#define aaa system("pause");
#define dbg(x) cerr<<(#x)<<": "<<(x)<<'\n',aaa
#define dbga(x,n) cerr<<(#x)<<"[]: ";for(int _=0;_<n;_++)cerr<<x[_]<<' ';cerr<<'\n',aaa
#define dbgs(x) cerr<<(#x)<<"[stl]: ";for(auto _:x)cerr<<_<<' ';cerr<<'\n',aaa
#define dbgp(x) cerr<<(#x)<<": "<<x.fi<<' '<<x.se<<'\n',aaa
#define maxn 1000

using namespace std;

const int dim = maxn*(maxn+3)+5;
int v[maxn+5][maxn+5], dist[dim], grad[dim], dx[4] = {-1, 0, 1, 0}, dy[4] = {0, -1, 0, 1};
int color[dim];
vi g[dim], gt[dim];

void umax(int &a, int b) { a = max(a, b); }
int id (int x, int y) { return x*(maxn+2)+y; }

void ciclu () {
  cout << "Poor Inna!\n";
  exit(0);
}

int tip (int x) {
  int i = x/(maxn+2), j = x%(maxn+2);
  return v[i][j];
}

void df (int nod) { ///ms mredingoda pt ciclu in gd
  color[nod] = 1;
  for (int nn: g[nod]) {
    if (color[nn] == 1) ciclu();
    if (color[nn] == 0) df(nn);
  }
  color[nod] = 2;
}

int main () {
  ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
  int n, m; cin >> n >> m;
  int i, j, z;
  string s;
  for (i = 1; i <= n; i++) {
    cin >> s;
    s = " " + s;
    for (j = 1; j <= m; j++) {
      if (s[j] == 'D') v[i][j] = 1;
      if (s[j] == 'I') v[i][j] = 2;
      if (s[j] == 'M') v[i][j] = 3;
      if (s[j] == 'A') v[i][j] = 4;
    }
  }
  int x, y, p = 0;///p = nr muchii
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++)
      for (z = 0; z < 4; z++) {
        x = i + dx[z]; y = j + dy[z];
        if (v[i][j]%4+1 == v[x][y]) {
          g[id(i,j)].pb(id(x,y));
          gt[id(x,y)].pb(id(i,j));
          p++;
        }
      }
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++)
      if (color[id(i,j)] == 0) df(id(i,j));
  queue<int> qu;
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++) {
      z = id(i, j);
      grad[z] = sz(gt[z]);
      if (grad[z] == 0) qu.push(z);
    }
  fill(all(dist), -inf);
  int ans = -inf;
  while (!qu.empty()) {
    int x = qu.front(); qu.pop();
    for (int nn: gt[x]) umax(dist[x], dist[nn]+1);
    if (tip(x) == 1) umax(dist[x], 1);
    umax(ans, dist[x]);
    for (int nn: g[x]) {
      grad[nn]--;
      if (grad[nn] == 0) qu.push(nn);
    }
  }
  if (ans < 4) cout << "Poor Dima!\n";
  else cout << ans/4;
  return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define pil pair<int,ll>
#define fi first
#define se second
#define inf (INT_MAX/2-1)
#define infl (1LL<<60)
#define vi vector<int>
#define vl vector<ll>
#define pb push_back
#define sz(a) (int)(a).size()
#define all(a) begin(a),end(a)
#define y0 y5656
#define y1 y7878
#define y2 y9090
#define aaa system("pause");
#define dbg(x) cerr<<(#x)<<": "<<(x)<<'\n',aaa
#define dbga(x,n) cerr<<(#x)<<"[]: ";for(int _=0;_<n;_++)cerr<<x[_]<<' ';cerr<<'\n',aaa
#define dbgs(x) cerr<<(#x)<<"[stl]: ";for(auto _:x)cerr<<_<<' ';cerr<<'\n',aaa
#define dbgp(x) cerr<<(#x)<<": "<<x.fi<<' '<<x.se<<'\n',aaa
#define maxn 1000

using namespace std;

const int dim = maxn*(maxn+3)+5;
int v[maxn+5][maxn+5], dist[dim], grad[dim], dx[4] = {-1, 0, 1, 0}, dy[4] = {0, -1, 0, 1};
bool viz[dim];
vi g[dim], gt[dim];

void umax(int &a, int b) { a = max(a, b); }
int id (int x, int y) { return x*(maxn+2)+y; }

void ciclu () {
  cout << "Poor Inna!\n";
  exit(0);
}

int tip (int x) {
  int i = x/(maxn+2), j = x%(maxn+2);
  return v[i][j];
}

void dag (int nod) {
  if (viz[nod]) ciclu();
  viz[nod] = 1;
  for (int nn: g[nod]) dag(nn);
  viz[nod] = 0;
}

int main () {
  ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
  int n, m; cin >> n >> m;
  int i, j, z;
  string s;
  for (i = 1; i <= n; i++) {
    cin >> s;
    s = " " + s;
    for (j = 1; j <= m; j++) {
      if (s[j] == 'D') v[i][j] = 1;
      if (s[j] == 'I') v[i][j] = 2;
      if (s[j] == 'M') v[i][j] = 3;
      if (s[j] == 'A') v[i][j] = 4;
    }
  }
  int x, y;
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++)
      for (z = 0; z < 4; z++) {
        x = i + dx[z]; y = j + dy[z];
        if (v[i][j]%4+1 == v[x][y]) {
          g[id(i,j)].pb(id(x,y));
          gt[id(x,y)].pb(id(i,j));
        }
      }
  bool in = 0;
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++)
      if (sz(gt[id(i,j)]) == 0) {
        dag(id(i,j));
        in = 1;
      }
  if (!in) ciclu();
  queue<int> qu;
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++) {
      z = id(i, j);
      grad[z] = sz(gt[z]);
      if (grad[z] == 0) qu.push(z);
    }
  fill(all(dist), -inf);
  int ans = -inf;
  while (!qu.empty()) {
    int x = qu.front(); qu.pop();
    for (int nn: gt[x]) umax(dist[x], dist[nn]+1);
    if (tip(x) == 1) umax(dist[x], 1);
    umax(ans, dist[x]);
    for (int nn: g[x]) {
      grad[nn]--;
      if (grad[nn] == 0) qu.push(nn);
    }
  }
  if (ans < 4) cout << "Poor Dima!\n";
  else cout << ans/4;
  return 0;
}


//Chirfen 2016.8.19

//

//
//http://acm.hust.edu.cn/vjudge/contest/129201#problem/C

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <map>

#define SIZE 500010
#define ll long long

using namespace std;
int n ,m , flag = 0;
char a[1001][1001];
bool vis[1001][1001];
char code[4] = {'D','I','M','A'};
int dis[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
int dfs(int x, int y , int dep, int res)
{
    if(a[x][y] != code[dep]) return res;
    if(vis[x][y] == true) {cout << "Poor Inna!"<< endl; flag = 1 ; return 0;}
    if(dep == 3) res++;
    int temp = res;
    for(int i = 0; i< 4 ; i++)
    {
        int dx = x + dis[i][0] , dy = y + dis[i][1];
        if(dx>= 0 && dx < n && dy >= 0 && dy < m)
        {
            vis[x][y] = true;
            temp=max(temp,dfs(dx,dy,(dep+1)%4,res));
            vis[x][y] = false;
        }

    }
    res = temp;
    return res;
}
int main()
{
    cin >> n >>m;
    bool numOfD = 0;
    int ans = 0;
    getchar();
    for(int i = 0 ; i < n ; i++)
    {
        for(int k = 0 ; k < m ; k++)
        {
            scanf("%c",&a[i][k]);
            if(a[i][k] == 'D') numOfD = 1;
        }
        getchar();
    }

    if(!numOfD) {cout << "Poor Dima!"<< endl; return 0;}
    for(int i = 0 ; i < n ; i++)
        for(int k = 0 ; k < m ; k++)
        {
            memset(vis,0,sizeof vis);
            ans = max(ans,dfs(i,k,0,0));
            if(flag) return 0;
        }

    if(ans == 0) {cout << "Poor Dima!"<< endl; return 0;}
    else {cout << ans << endl;}
    return 0;
}


//Chirfen 2016.8.19

//
//
//http://acm.hust.edu.cn/vjudge/contest/129201#problem/C

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <map>

#define SIZE 500010
#define ll long long

using namespace std;
int n ,m , flag = 0;
char a[1001][1001];
bool vis[1001][1001];
int record[1001][1001];
char code[4] = {'D','I','M','A'};
int dis[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
int dfs(int x, int y , int dep, int res)
{
    if(a[x][y] != code[dep]) return res;
    if(vis[x][y] == true) {flag = 1 ; return 0;}
    if(dep == 3) res++;
    if(record[x][y]) return res+record[x][y];
    int temp = res;
    for(int i = 0; i< 4 ; i++)
    {
        int dx = x + dis[i][0] , dy = y + dis[i][1];
        if(dx>= 0 && dx < n && dy >= 0 && dy < m)
        {
            vis[x][y] = true;
            temp=max(temp,dfs(dx,dy,(dep+1)%4,res));
            vis[x][y] = false;
        }
    }
    record[x][y] = temp -res;
    res = temp;
    return res;
}
int main()
{
    cin >> n >>m;
    bool numOfD = 0;
    int ans = 0;
    getchar();
    for(int i = 0 ; i < n ; i++)
    {
        for(int k = 0 ; k < m ; k++)
        {
            scanf("%c",&a[i][k]);
            if(a[i][k] == 'D') numOfD = 1;
        }
        getchar();
    }

    if(!numOfD) {cout << "Poor Dima!"<< endl; return 0;}
    if(numOfD == n*m) {cout << "Poor Dima!"<< endl; return 0;}
    for(int i = 0 ; i < n ; i++)
        for(int k = 0 ; k < m ; k++)
        {
            ans = max(ans,dfs(i,k,0,0));
            if(flag) {cout << "Poor Inna!"<< endl;return 0;}
        }

    if(ans == 0) {cout << "Poor Dima!"<< endl; return 0;}
    else {cout << ans << endl;}
    return 0;
}


//Chirfen 2016.8.19

//
//
//http://acm.hust.edu.cn/vjudge/contest/129201#problem/C

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <map>

#define SIZE 500010
#define ll long long

using namespace std;
int n ,m , flag = 0;
char a[1001][1001];
bool vis[1001][1001];
int record[1001][1001];
char code[4] = {'D','I','M','A'};
int dis[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
int dfs(int x, int y , int dep, int res)
{
    if(a[x][y] != code[dep]) return res;
    if(vis[x][y] == true) {flag = 1 ; return 0;}
    if(dep == 3) res++;
    if(record[x][y]) return res+record[x][y];
    int temp = res;
    for(int i = 0; i< 4 ; i++)
    {
        int dx = x + dis[i][0] , dy = y + dis[i][1];
        if(dx>= 0 && dx < n && dy >= 0 && dy < m)
        {
            vis[x][y] = true;
            temp=max(temp,dfs(dx,dy,(dep+1)%4,res));
            vis[x][y] = false;
        }
    }
    record[x][y] = temp -res;
    res = temp;
    return res;
}
int main()
{
    cin >> n >>m;
    bool numOfD = 0;
    int ans = 0;
    getchar();
    for(int i = 0 ; i < n ; i++)
    {
        for(int k = 0 ; k < m ; k++)
        {
            scanf("%c",&a[i][k]);
            if(a[i][k] == 'D') numOfD = 1;
        }
        getchar();
    }

    if(!numOfD) {cout << "Poor Dima!"<< endl; return 0;}
    for(int i = 0 ; i < n ; i++)
        for(int k = 0 ; k < m ; k++)
        {
            memset(vis,0,sizeof vis);
            ans = max(ans,dfs(i,k,0,0));
            if(flag) {cout << "Poor Inna!"<< endl;return 0;}
        }

    if(ans == 0) {cout << "Poor Dima!"<< endl; return 0;}
    else {cout << ans << endl;}
    return 0;
}


//Chirfen 2016.8.19

//

//
//http://acm.hust.edu.cn/vjudge/contest/129201#problem/C

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <map>

#define SIZE 500010
#define ll long long

using namespace std;
int n ,m , flag = 0;
char a[1001][1001];
bool vis[1001][1001];
char code[4] = {'D','I','M','A'};
int dis[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
int dfs(int x, int y , int dep, int res)
{
    if(a[x][y] != code[dep]) return res;
    if(vis[x][y] == true) {flag = 1 ; return 0;}
    if(dep == 3) res++;
    int temp = res;
    for(int i = 0; i< 4 ; i++)
    {
        int dx = x + dis[i][0] , dy = y + dis[i][1];
        if(dx>= 0 && dx < n && dy >= 0 && dy < m)
        {
            vis[x][y] = true;
            temp=max(temp,dfs(dx,dy,(dep+1)%4,res));
            vis[x][y] = false;
        }

    }
    res = temp;
    return res;
}
int main()
{
    cin >> n >>m;
    bool numOfD = 0;
    int ans = 0;
    getchar();
    for(int i = 0 ; i < n ; i++)
    {
        for(int k = 0 ; k < m ; k++)
        {
            scanf("%c",&a[i][k]);
            if(a[i][k] == 'D') numOfD = 1;
        }
        getchar();
    }

    if(!numOfD) {cout << "Poor Dima!"<< endl; return 0;}
    for(int i = 0 ; i < n ; i++)
        for(int k = 0 ; k < m ; k++)
        {
            memset(vis,0,sizeof vis);
            ans = max(ans,dfs(i,k,0,0));
            if(flag) {cout << "Poor Inna!"<< endl;return 0;}
        }

    if(ans == 0) {cout << "Poor Dima!"<< endl; return 0;}
    else {cout << ans << endl;}
    return 0;
}