Problem p00770 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;

#define rep(i, x, y) for (int i = (x); i < (y); ++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define dump(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define dump(x)
#endif

typedef long long int ll;
typedef pair<int, int> pii;
// template<typename T> using vec=std::vector<T>;

const int inf = 1 << 30;
const long long int infll = 1LL << 58;
const double eps = 1e-9;
const int dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1};

namespace std {
template <> class hash<std::pair<int, int>> {
public:
  size_t operator()(const std::pair<int, int> &x) const {
    return size_t((size_t)x.first * (size_t)x.second);
  }
};
} // namespace std

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (const auto &v : vec) {
    os << v << ",";
  }
  os << "]";
  return os;
}

void solve() {
  vector<bool> is_prime(1e6 + 1, true);
  is_prime[0] = is_prime[1] = false;
  rep(i, 2, 1e+6 + 1) {
    if (!is_prime[i])
      continue;
    for (int j = i * 2; j < 1e6 + 1; j += i)
      is_prime[j] = false;
  }
  while (true) {
    int m, n;
    cin >> m >> n;
    if (m == 0 and n == 0)
      break;

    unordered_map<pii, int> encode;
    unordered_map<int, pii> decode;
    unordered_map<int, vector<int>> xs;
    {
      int x = 0, y = 0, dir = 3;
      rep(i, 1, m + 1) {
        encode[make_pair(x, y)] = i;
        decode[i] = make_pair(x, y);
        xs[y].push_back(x);
        int nx = x + dx[(dir + 1) % 4], ny = y + dy[(dir + 1) % 4];
        if (encode.find(make_pair(nx, ny)) == encode.end())
          dir = (dir + 1) % 4;
        else {
          nx = x + dx[dir];
          ny = y + dy[dir];
        }
        x = nx;
        y = ny;
      }
    }

    unordered_map<pii, int> dp;
    int y = decode[n].second + 1, ans, max_num;
    if (is_prime[n]) {
      dp[decode[n]] = 1;
      ans = 1;
      max_num = n;
    } else {
      dp[decode[n]] = 0;
      ans = 0;
      max_num = 0;
    }
    while (xs.find(y) != xs.end()) {
      if (xs.find(y - 2) != xs.end())
        for (int x : xs[y - 2])
          dp.erase(make_pair(x, y));
      for (int x : xs[y]) {
        int tmp = -1;
        if (dp.find(make_pair(x - 1, y - 1)) != dp.end())
          tmp = max(tmp, dp[make_pair(x - 1, y - 1)]);
        if (dp.find(make_pair(x, y - 1)) != dp.end())
          tmp = max(tmp, dp[make_pair(x, y - 1)]);
        if (dp.find(make_pair(x + 1, y - 1)) != dp.end())
          tmp = max(tmp, dp[make_pair(x + 1, y - 1)]);
        if (tmp == -1)
          continue;
        if (is_prime[encode[make_pair(x, y)]]) {
          ++tmp;
          if (tmp > ans) {
            ans = tmp;
            max_num = encode[make_pair(x, y)];
          } else if (tmp == ans)
            max_num = max(max_num, encode[make_pair(x, y)]);
        }
        dp[make_pair(x, y)] = tmp;
      }
      ++y;
    }

    cout << ans << " " << max_num << endl;
  }
}

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);
  solve();
  return 0;
}

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

#define rep(i, x, y) for (int i = (x); i < (y); ++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define dump(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define dump(x)
#endif

typedef long long int ll;
typedef pair<int, int> pii;
// template<typename T> using vec=std::vector<T>;

const int inf = 1 << 30;
const long long int infll = 1LL << 58;
const double eps = 1e-9;
const int dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1};

namespace std {
template <> class hash<std::pair<int, int>> {
public:
  size_t operator()(const std::pair<int, int> &x) const {
    return size_t((size_t)x.first * (size_t)x.second);
  }
};
} // namespace std

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (const auto &v : vec) {
    os << v << ",";
  }
  os << "]";
  return os;
}

void solve() {
  vector<bool> is_prime(1e6 + 1, true);
  is_prime[0] = is_prime[1] = false;
  rep(i, 2, 1e+6 + 1) {
    if (!is_prime[i])
      continue;
    for (int j = i * 2; j < 1e6 + 1; j += i)
      is_prime[j] = false;
  }
  while (true) {
    int m, n;
    cin >> m >> n;
    if (m == 0 and n == 0)
      break;

    unordered_map<pii, int> encode;
    unordered_map<int, pii> decode;
    unordered_map<int, vector<int>> xs;
    {
      int x = 0, y = 0, dir = 3;
      rep(i, 1, m + 1) {
        encode[make_pair(x, y)] = i;
        decode[i] = make_pair(x, y);
        xs[y].push_back(x);
        int nx = x + dx[(dir + 1) % 4], ny = y + dy[(dir + 1) % 4];
        if (encode.find(make_pair(nx, ny)) == encode.end())
          dir = (dir + 1) % 4;
        else {
          nx = x + dx[dir];
          ny = y + dy[dir];
        }
        x = nx;
        y = ny;
      }
    }

    unordered_map<pii, int> dp;
    int y = decode[n].second + 1, ans, max_num;
    if (is_prime[n]) {
      dp[decode[n]] = 1;
      ans = 1;
      max_num = n;
    } else {
      dp[decode[n]] = 0;
      ans = 0;
      max_num = 0;
    }
    while (xs.find(y) != xs.end()) {
      if (xs.find(y - 2) != xs.end())
        for (int x : xs[y - 2])
          dp.erase(make_pair(x, y - 2));
      for (int x : xs[y]) {
        int tmp = -1;
        if (dp.find(make_pair(x - 1, y - 1)) != dp.end())
          tmp = max(tmp, dp[make_pair(x - 1, y - 1)]);
        if (dp.find(make_pair(x, y - 1)) != dp.end())
          tmp = max(tmp, dp[make_pair(x, y - 1)]);
        if (dp.find(make_pair(x + 1, y - 1)) != dp.end())
          tmp = max(tmp, dp[make_pair(x + 1, y - 1)]);
        if (tmp == -1)
          continue;
        if (is_prime[encode[make_pair(x, y)]]) {
          ++tmp;
          if (tmp > ans) {
            ans = tmp;
            max_num = encode[make_pair(x, y)];
          } else if (tmp == ans)
            max_num = max(max_num, encode[make_pair(x, y)]);
        }
        dp[make_pair(x, y)] = tmp;
      }
      ++y;
    }

    cout << ans << " " << max_num << endl;
  }
}

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);
  solve();
  return 0;
}