Problem p00770 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <iostream>

#define MAX_M 1000000

using namespace std;

typedef struct {
  int num, prime, last;
} HOLE;

int M, N;
HOLE h[1000 + 2][1000 + 2];

bool prime_judge(int x) {
  if (x == 0 || x == 1)
    return false;
  for (int i = 2; i * i <= x; i++) {
    if (x % i == 0)
      return false;
  }
  return true;
}

void solve() {
  int flag = 0, d = 1; //?????????????????????, ???????????¢
  int x = 501, y = 501, ox = 501, oy = 501;
  int ansx, ansy;
  for (int i = 0; i < 1002; i++) {
    for (int j = 0; j < 1002; j++) {
      h[i][j].num = 0;
      h[i][j].last = 0;
      h[i][j].prime = 0;
    }
  }
  for (int i = 1; i <= M; i++) {
    h[x][y].num = i;
    if (i == N) {
      ansx = x;
      ansy = y;
    }
    if (flag == 0) {
      x++;
      if (x - ox == d) {
        ox = x;
        flag = 1;
      }
    } else if (flag == 1) {
      y--;
      if (oy - y == d) {
        oy = y;
        d++;
        flag = 2;
      }
    } else if (flag == 2) {
      x--;
      if (ox - x == d) {
        ox = x;
        flag = 3;
      }
    } else if (flag == 3) {
      y++;
      if (y - oy == d) {
        oy = y;
        d++;
        flag = 0;
      }
    }
  }
  for (int i = 1001; i >= 0; i--) {
    for (int j = 0; j < 1002; j++) {
      if (h[j][i].num != 0) {
        h[j][i].prime = max(max(h[j - 1][i + 1].prime, h[j][i + 1].prime),
                            h[j + 1][i + 1].prime);
        if (h[j - 1][i + 1].last == 0 && h[j][i + 1].last == 0 &&
            h[j + 1][i + 1].last == 0) {
          if (prime_judge(h[j][i].num))
            h[j][i].last = h[j][i].num;
        } else {
          int k;
          for (k = -1; k <= 1; k++) {
            if (h[j + k][i + 1].prime == h[j][i].prime) {
              h[j][i].last = h[j + k][i + 1].last;
              break;
            }
          }
          for (int l = -1; l <= 1; l++) {
            if (h[j + k][i + 1].prime == h[j + l][i + 1].prime) {
              h[j][i].last = max(h[j][i].last, h[j + l][i + 1].last);
            }
          }
        }
        if (prime_judge(h[j][i].num))
          h[j][i].prime++;
      }
    }
  }
  if (h[ansx][ansy].prime == 0)
    cout << "0 0" << endl;
  else
    cout << h[ansx][ansy].prime << " " << h[ansx][ansy].last << endl;
}

int main() {
  while (1) {
    cin >> M >> N;
    if (M == 0 && N == 0)
      break;
    solve();
  }
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <iostream>

#define MAX_M 1000000

using namespace std;

typedef struct {
  int num, prime, last;
} HOLE;

int M, N;
HOLE h[1000 + 2][1000 + 2];

bool prime_judge(int x) {
  if (x == 0 || x == 1)
    return false;
  for (int i = 2; i * i <= x; i++) {
    if (x % i == 0)
      return false;
  }
  return true;
}

void solve() {
  int flag = 0, d = 1; //?????????????????????, ???????????¢
  int x = 500, y = 500, ox = 500, oy = 500;
  int ansx, ansy;
  for (int i = 0; i < 1002; i++) {
    for (int j = 0; j < 1002; j++) {
      h[i][j].num = 0;
      h[i][j].last = 0;
      h[i][j].prime = 0;
    }
  }
  for (int i = 1; i <= M; i++) {
    h[x][y].num = i;
    if (i == N) {
      ansx = x;
      ansy = y;
    }
    if (flag == 0) {
      x++;
      if (x - ox == d) {
        ox = x;
        flag = 1;
      }
    } else if (flag == 1) {
      y--;
      if (oy - y == d) {
        oy = y;
        d++;
        flag = 2;
      }
    } else if (flag == 2) {
      x--;
      if (ox - x == d) {
        ox = x;
        flag = 3;
      }
    } else if (flag == 3) {
      y++;
      if (y - oy == d) {
        oy = y;
        d++;
        flag = 0;
      }
    }
  }
  for (int i = 1001; i >= 0; i--) {
    for (int j = 0; j < 1002; j++) {
      if (h[j][i].num != 0) {
        h[j][i].prime = max(max(h[j - 1][i + 1].prime, h[j][i + 1].prime),
                            h[j + 1][i + 1].prime);
        if (h[j - 1][i + 1].last == 0 && h[j][i + 1].last == 0 &&
            h[j + 1][i + 1].last == 0) {
          if (prime_judge(h[j][i].num))
            h[j][i].last = h[j][i].num;
        } else {
          int k;
          for (k = -1; k <= 1; k++) {
            if (h[j + k][i + 1].prime == h[j][i].prime) {
              h[j][i].last = h[j + k][i + 1].last;
              break;
            }
          }
          for (int l = -1; l <= 1; l++) {
            if (h[j + k][i + 1].prime == h[j + l][i + 1].prime) {
              h[j][i].last = max(h[j][i].last, h[j + l][i + 1].last);
            }
          }
        }
        if (prime_judge(h[j][i].num))
          h[j][i].prime++;
      }
    }
  }
  if (h[ansx][ansy].prime == 0)
    cout << "0 0" << endl;
  else
    cout << h[ansx][ansy].prime << " " << h[ansx][ansy].last << endl;
}

int main() {
  while (1) {
    cin >> M >> N;
    if (M == 0 && N == 0)
      break;
    solve();
  }
  return 0;
}