/*
 * Решение задачи L2. Dumbness of the Ancients 2
 *
 * В данном решении используется перебор с запоминанием. Находясь в клетке с только что убитым
 * врагом (или в стартовой клетке), мы попробуем пойти во все клетки с ещё не убитыми врагами,
 * посчитаем, какое максимальное количество врагов в результате получится убить, и выберем максимум.
 *
 * Для оптимизации перебора будем запоминать результат по состоянию - номеру врага E(nemy), в клетке
 * с которым мы сейчас находимся, и множеству уже убитых врагов, заданному битовой маской M(ask).
 * Для каждого состояния нужно хранить время T(ime), за которое был достигнут текущий враг E, и
 * количество врагов K(ills), которых ещё получится убить (в данном решении - считая текущего врага
 * E, но можно сделать и иначе). Получается, что у нас будет храниться соответствие
 * (E, M) -> (T, K).
 *
 * Во время перебора текущее состояние будет описываться текущим врагом E', множеством убитых
 * врагов M' и прошедшим временем T'. Начнём перебор с состояния (-1, 0, 0), где E' = -1 обозначает,
 * что мы стоим в клетке (1, 1), в которой нет врага. Далее мы начнём пробовать рекурсивно
 * переходить во всех ещё не убитых врагов (тех, которых нет в M') и считать, сколько врагов
 * получится убить при таком переходе. Из всех вариантов выберем максимальный и вернём его в
 * качестве ответа K' для текущего состояния.
 *
 * Пользоваться запомненными результатами будем следующим образом. Допустим мы находимся в состоянии
 * (E', M', T'). Тогда:
 *
 * - если у нас есть запомненный результат для (E', M') и T' = T, то сразу вернём запомненное K в
 *   качестве результата
 *
 * - если есть запомненный результат для (E', M'), но T' > T, то рассмотренный ранее способ
 *   достижения состояния (E', M') был лучше и текущую ветку перебора можно отбросить
 *
 * - если есть запомненный результат для (E', M'), но T' < T, то нужно заново пересчитать результат
 *   для текущего состояния перебором, получить новое количество убитых врагов K' и запомнить
 *   (E', M') -> (T', K')
 *
 * - если для состояния (E', M') нет сохранённого результата, нужно рассчиать его перебором и тоже
 *   запомнить
 *
 * Результат, возвращённый для (-1, 0, 0) и будет ответом.
 *
 * Точную сложность решения я назвать затрудняюсь, но если пересчётов (случаев T' < T) будет мало,
 * то она будет близка к N * 2^N, что вполне приемлемо для данной задачи. Если вместо рекурсивных
 * вызовов заполнить таблицу (E, M) -> (T, K) в правильном порядке, то можно избежать пересчётов.
 *
 * Следует отметить, что в данной реализации вместо рекурсивных вызовов используется стек состояний
 * и возвращаемых из состояний результатов. При этом каждое состояние обрабатывается в два этапа. На
 * первом этапе генерируются вызовы других состояний, а на втором из стека результатов забираются
 * результаты, возвращённые теми состояниями, и помещается результат для текущего состояния. После
 * этого текущее состояние удаляется из стека состояний. Короче говоря, прямая эмуляция рекурсивных
 * вызовов. Вообще говоря, это излишне, поскольку глубина рекурсии не будет превышать N, то есть 13.
 *
 * Автор решения: Вова Мшанецкий, vovams163@(почтовый сервер гугла)
 */

#include <cstdio>
#include <cmath>
#include <stack>
#include <algorithm>

using namespace std;

static const int MAX_ENEMIES = 13;
static const int MAX_BOARD_SIDE = 50;
static const int INF_TIME = MAX_BOARD_SIDE * MAX_BOARD_SIDE * MAX_ENEMIES;

struct Enemy
{
    int row;
    int col;
    int health;
};

struct StackFrame
{
    int curEnemy;
    int killMask;
    int timeElapsed;
    
    bool firstPass;
    
    StackFrame(int curEnemy, int killMask, int timeElapsed)
        : curEnemy(curEnemy),
          killMask(killMask),
          timeElapsed(timeElapsed),
          firstPass(true)
    {
    }
};

struct CacheEntry
{
    int reachTime;
    int maxKills;
};

static int manhattanDist2D(const Enemy& a, const Enemy& b);

int main()
{

...