Problem:
問題 D : 停止問題
G○○gle Code Jam は G○○gle 社が年に 1 度開催するコンテストである．
優勝者は G○○gle への入社を許される，世界最高峰のコンテストだ．
しかし勿論，それ以外の参加者は帰らぬ者となる．
G○○gle Code Jam では自分の好きなプログラミング言語や処理系を使うことができる．
僕は Defunge という自らが開発したプログラミング言語で参加することにした．
この言語を使えば，計算困難な問題はおろか，判定不能な問題ですら解決できる気がしている．
問題
与えられるプログラムが停止するかを判定するプログラムを作成せよ．
与えられるプログラムは，以下で説明するプログラミング言語 Defunge で記述されている．
Defunge のプログラムの命令は 1 文字であり，1 次元の列ではなく 2 次元の格子状に並んでいる．
下図は，Defunge のプログラムの例である:
6>--v.
.^--_@
Defunge の言語仕様は以下のようになっている．
Defunge のプログラムは、左上のマスから右向きで開始する． （左上のマスの命令が最初に実行される．）
命令によって進む向きが上下左右に変更されることがある．
端に達したら反対側の端へジャンプする．
メモリは 0 から 15 までの 1 つの整数を記憶することができる．
メモリにははじめ 0 が記憶されている．
Defunge の命令は以下の通りである．
'<' … 実行の向きを左にする．
'>' … 実行の向きを右にする．
'^' … 実行の向きを上にする．
'v' … 実行の向きを下にする．
'_' … メモリの値が 0 ならば実行の向きを右に，そうでなければ左にする．
'|' … メモリの値が 0 ならば実行の向きを下に，そうでなければ上にする．
'?' … 実行の向きが上下左右のいずれかにランダムに等確率で変更される．
'.' … 何もしない．
'@' … プログラムの実行を停止する．
'0' - '9' … メモリの値を指定の数値にする．
'+' … メモリの値に 1 を加える，ただし値が 15 だった場合 0 にする．
'-' … メモリの値から 1 を引く，ただし値が 0 だった場合 15 にする．
入力
入力の最初の行は 2 つの整数 R, C を含む．
続く R 行はプログラムを表す。それぞれ C 文字の文字列を含む。
出力
プログラムが停止する可能性がある場合は YES と出力せよ．
そうでないとき，NO と出力せよ．
制約
1 ≤
R
≤ 20
1 ≤
C
≤ 20
入出力例
入出力例 1
入力例 1:
2 6
6>--v.
.^--_@
入力例 1 に対する出力:
YES
入出力例 2
入力例 2:
2 6
5>--v.
.^--_@
入力例 2 に対する出力:
NO
入出力例 3
入力例 3:
2 6
.>--v.
.^--?@
入力例 3 に対する出力:
YES
補足
Defunge は Befunge と類似している．
Befunge の理解は Defunge の理解を助けるかもしれないが，
異なる点も多いため，注意せよ．
http://ja.wikipedia.org/wiki/Befunge

Submitted solutions:

code_snippet: /*                 _        ____              */
/*   AC        U  /"\  u U /"___|     AC      */
/*              \/ _ \/  \| | u               */
/*        AC    / ___ \   | |/__    AC        */
/*             /_/   \_\   \____|             */
/* AC           \\    >>  _// \\         AC   */
/*             (__)  (__)(__)(__)             */
/*          github.com/NULLCT/Compro          */

#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2")

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <cinttypes>
#include <climits>
#include <cmath>
#include <complex>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <stdexcept>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <valarray>
#include <vector>

#define int long long
#define double long double
#define rep(i, e) for (int i = 0; i < (e); i++)
#define ALL(var) begin(var), end(var)
#ifdef DEBUG
#define D(var) cerr << __LINE__ << ":" << #var << " " << var << endl;
#define DD(var) for_each(begin(var), end(var), [](const auto &i) { D(i); })
#else
#define D(var) ;
#define DD(var) ;
#endif

using namespace std;

constexpr int INF = 1LL << 60;

template <class T, size_t S>
ostream &operator<<(ostream &_ostr, const array<T, S> &_v);
template <class T>
ostream &operator<<(ostream &_ostr, const vector<T> &_v);
template <class T>
ostream &operator<<(ostream &_ostr, const valarray<T> &_v);
template <class T>
ostream &operator<<(ostream &_ostr, const deque<T> &_v);
template <class T>
ostream &operator<<(ostream &_ostr, const list<T> &_v);
template <class T, class Y>
ostream &operator<<(ostream &_ostr, const pair<T, Y> &_v);
template <class... Ts>
ostream &operator<<(ostream &_ostr, const tuple<Ts...> &t);
template <class T, class Y>
ostream &operator<<(ostream &_ostr, const map<T, Y> &_v);
template <class T, class Y>
ostream &operator<<(ostream &_ostr, const multimap<T, Y> &_v);
template <class T, class Y>
ostream &operator<<(ostream &_ostr, const unordered_map<T, Y> &_v);
template <class T, class Y>
ostream &operator<<(ostream &_ostr, const unordered_multimap<T, Y> &_v);
template <class T>
ostream &operator<<(ostream &_ostr, const set<T> &_v);
template <class T>
ostream &operator<<(ostream &_ostr, const multiset<T> &_v);
template <class T>
ostream &operator<<(ostream &_ostr, const unordered_set<T> &_v);
template <class T>
ostream &operator<<(ostream &_ostr, const unordered_multiset<T> &_v);

template <class T>
ostream &_orange(ostream &_ostr, const T &_v) {
  if (_v.size() == 0)
    return _ostr;
  _ostr << *begin(_v);
  for (auto itr = next(begin(_v)), enditr = end(_v); itr != enditr; itr++)
    _ostr << " " << *itr;
  return _ostr;
}
template <class T, size_t S>
ostream &operator<<(ostream &_ostr, const array<T, S> &_v) { return _orange(_ostr, _v); }
template <class T>
ostream &operator<<(ostream &_ostr, const vector<T> &_v) { return _orange(_ostr, _v); }
template <class T>
ostream &operator<<(ostream &_ostr, const valarray<T> &_v) { return _orange(_ostr, _v); }
template <class T>
ostream &operator<<(ostream &_ostr, const deque<T> &_v) { return _orange(_ostr, _v); }
template <class T>
ostream &operator<<(ostream &_ostr, const list<T> &_v) { return _orange(_ostr, _v); }
template <class T, class Y>
ostream &operator<<(ostream &_ostr, const pair<T, Y> &_v) { return _orange(_ostr, _v); }
template <class... Ts>
ostream &operator<<(ostream &_ostr, const tuple<Ts...> &_v) {
  bool first = true;
  apply([&_ostr, &first](auto &&...args) {
    auto print = [&](auto &&val) {
      if (!first)
        _ostr << " ";
      (_ostr << val);
      first = false;
    };
    (print(args), ...);
  },
        _v);
  return _ostr;
}
template <class T, class Y>
ostream &operator<<(ostream &_ostr, const map<T, Y> &_v) { return _orange(_ostr, _v); }
template <class T, class Y>
ostream &operator<<(ostream &_ostr, const multimap<T, Y> &_v) { return _orange(_ostr, _v); }
template <class T, class Y>
ostream &operator<<(ostream &_ostr, const unordered_map<T, Y> &_v) { return _orange(_ostr, _v); }
template <class T>
ostream &operator<<(ostream &_ostr, const set<T> &_v) { return _orange(_ostr, _v); }
template <class T>
ostream &operator<<(ostream &_ostr, const multiset<T> &_v) { return _orange(_ostr, _v); }
template <class T>
ostream &operator<<(ostream &_ostr, const unordered_set<T> &_v) { return _orange(_ostr, _v); }
template <class T>
ostream &operator<<(ostream &_ostr, const unordered_multiset<T> &_v) { return _orange(_ostr, _v); }

template <class T, size_t S>
istream &operator>>(istream &_istr, array<T, S> &_v);
template <class T>
istream &operator>>(istream &_istr, vector<T> &_v);
template <class T>
istream &operator>>(istream &_istr, valarray<T> &_v);
template <class T>
istream &operator>>(istream &_istr, deque<T> &_v);
template <class T, class Y>
istream &operator>>(istream &_istr, pair<T, Y> &_v);

template <class T>
istream &_irange(istream &_istr, T &_v) {
  for (auto &i : _v)
    _istr >> i;
  return _istr;
}
template <class T, size_t S>
istream &operator>>(istream &_istr, array<T, S> &_v) { return _irange(_istr, _v); }
template <class T>
istream &operator>>(istream &_istr, vector<T> &_v) { return _irange(_istr, _v); }
template <class T>
istream &operator>>(istream &_istr, valarray<T> &_v) { return _irange(_istr, _v); }
template <class T>
istream &operator>>(istream &_istr, deque<T> &_v) { return _irange(_istr, _v); }
template <class T, class Y>
istream &operator>>(istream &_istr, pair<T, Y> &_v) {
  for (auto &i : _v)
    _istr >> i.first >> i.second;
  return _istr;
}

vector<int> divisor(int n) {
  vector<int> head, tail;
  for (int i = 1; i * i <= n; i++) {
    if (n % i == 0) {
      head.push_back(i);
      if (i * i != n)
        tail.push_back(n / i);
    }
  }
  head.insert(head.end(), tail.rbegin(), tail.rend());
  return head;
}

vector<pair<int, int>> primeFactorize(int n) {
  vector<pair<int, int>> res;
  for (int a = 2; a * a <= n; ++a) {
    if (n % a != 0)
      continue;
    int ex = 0;
    while (n % a == 0)
      ++ex, n /= a;
    res.push_back({a, ex});
  }
  if (n != 1)
    res.push_back({n, 1});
  return res;
}

int dichotomy(int ng, int ok, function<bool(int)> discriminant) {
  while (ok - ng > 1) {
    int mid = (ng + ok) / 2;
    (discriminant(mid) ? ok : ng) = mid;
  }
  return ok;
}

template <class T>
vector<vector<T>> turnR(const vector<vector<T>> &s) {
  vector<vector<T>> res(s[0].size(), vector<T>(s.size()));
  for (int y = 0; y < s.size(); y++)
    for (int x = 0; x < s[0].size(); x++)
      res[x][s.size() - y - 1] = s[y][x];
  return res;
}

template <class T>
vector<vector<T>> turnL(const vector<vector<T>> &s) {
  vector<vector<T>> res(s[0].size(), vector<T>(s.size()));
  for (int y = 0; y < s.size(); y++)
    for (int x = 0; x < s[0].size(); x++)
      res[s[0].size() - x - 1][y] = s[y][x];
  return res;
}

int mop(int a, int n, int mod = INF) {
  int res = 1;
  while (n > 0) {
    if (n & 1)
      res = res * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return res;
}

template <class T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

template <class T>
bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

template <int Modulus>
class modint {
public:
  int n;
  constexpr modint(const int x = 0) noexcept : n(x % Modulus) {}
  constexpr int &value() noexcept { return n; }
  constexpr const int &value() const noexcept { return n; }
  constexpr modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
    n += rhs.n;
    if (n >= Modulus)
      n -= Modulus;
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if (n < rhs.n)
      n += Modulus;
    n -= rhs.n;
    return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
    n = n * rhs.n % Modulus;
    return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
    int exp = Modulus - 2;
    while (exp) {
      if (exp % 2)
        *this *= rhs;
      rhs *= rhs;
      exp /= 2;
    }
    return *this;
  }
  template <int mod>
  friend istream &operator>>(istream &_istr, modint<mod> &rhs) {
    _istr >> rhs.n;
    rhs.n %= Modulus;
    return _istr;
  }
  template <int mod>
  friend ostream &operator<<(ostream &_ostr, const modint<mod> &rhs) {
    return _ostr << rhs.n;
  }
};

template <class T>
class SegmentTree {
public:
  int sz;
  vector<T> seg;
  const function<T(T, T)> f;
  const T M1;
  SegmentTree(int n, const function<T(T, T)> _f, const T &_M1) : f(_f), M1(_M1) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    seg.assign(2 * sz, _M1);
  }
  void set(int k, const T &x) {
    seg[k + sz] = x;
  }
  void build() {
    for (int k = sz - 1; k > 0; k--)
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
  }
  void update(int k, const T &x) {
    k += sz;
    seg[k] = x;
    while (k >>= 1)
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
  }
  // O(log n)
  T query(int a, int b) {
    T L = M1, R = M1;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1)
        L = f(L, seg[a++]);
      if (b & 1)
        R = f(seg[--b], R);
    }
    return f(L, R);
  }
  T operator[](const int &k) const {
    return seg[k + sz];
  }
  template <class C>
  int find_subtree(int a, const C &check, T &M, bool type) {
    while (a < sz) {
      T nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);
      if (check(nxt))
        a = 2 * a + type;
      else
        M = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }
  template <class C>
  int find_first(int a, const C &check) {
    T L = M1;
    if (a <= 0) {
      if (check(f(L, seg[1])))
        return find_subtree(1, check, L, false);
      return -1;
    }
    int b = sz;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        T nxt = f(L, seg[a]);
        if (check(nxt))
          return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }
  template <class C>
  int find_last(int b, const C &check) {
    T R = M1;
    if (b >= sz) {
      if (check(f(seg[1], R)))
        return find_subtree(1, check, R, true);
      return -1;
    }
    int a = sz;
    for (b += sz; a < b; a >>= 1, b >>= 1) {
      if (b & 1) {
        T nxt = f(seg[--b], R);
        if (check(nxt))
          return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }
};

class UnionFind {
public:
  int n;
  vector<int> p;
  UnionFind(int _n) : n(_n), p(_n, -1) {}
  bool merge(int a, int b) {
    int x = root(a), y = root(b);
    if (x == y)
      return false;
    if (-p[x] < -p[y])
      swap(x, y);
    p[x] += p[y], p[y] = x;
    return true;
  }
  bool isSame(int a, int b) {
    return root(a) == root(b);
  }
  int root(int a) {
    if (p[a] < 0)
      return a;
    return p[a] = root(p[a]);
  }
  int size(int a) {
    return -p[root(a)];
  }
  vector<vector<int>> groups() {
    vector<int> buf(n), size(n);
    for (int i = 0; i < n; i++) {
      buf[i] = root(i);
      size[buf[i]]++;
    }
    vector<vector<int>> res(n);
    for (int i = 0; i < n; i++)
      res[i].reserve(size[i]);
    for (int i = 0; i < n; i++)
      res[buf[i]].push_back(i);
    res.erase(remove_if(res.begin(), res.end(), [&](const vector<int> &v) { return v.empty(); }), res.end());
    return res;
  }
};
class RollingHash {
  static constexpr unsigned mod = 1000000007;

public:
  vector<unsigned> hashed, power;
  inline unsigned mul(unsigned a, unsigned b) const {
    unsigned long long x = (unsigned long long)a * b;
    unsigned xh = (unsigned)(x >> 32), xl = (unsigned)x, d, m;
    asm("divl %4; \n\t"
        : "=a"(d), "=d"(m)
        : "d"(xh), "a"(xl), "r"(mod));
    return m;
  }
  RollingHash(const string &s, unsigned base = 10007) {
    int sz = (int)s.size();
    hashed.assign(sz + 1, 0);
    power.assign(sz + 1, 0);
    power[0] = 1;
    for (int i = 0; i < sz; i++) {
      power[i + 1] = mul(power[i], base);
      hashed[i + 1] = mul(hashed[i], base) + s[i];
      if (hashed[i + 1] >= mod)
        hashed[i + 1] -= mod;
    }
  }
  unsigned get(int l, int r) const {
    unsigned ret = hashed[r] + mod - mul(hashed[l], power[r - l]);
    if (ret >= mod)
      ret -= mod;
    return ret;
  }
  unsigned connect(unsigned h1, int h2, int h2len) const {
    unsigned ret = mul(h1, power[h2len]) + h2;
    if (ret >= mod)
      ret -= mod;
    return ret;
  }
  int LCP(const RollingHash &b, int l1, int r1, int l2, int r2) {
    int len = min(r1 - l1, r2 - l2);
    int low = -1, high = len + 1;
    while (high - low > 1) {
      int mid = (low + high) / 2;
      if (get(l1, l1 + mid) == b.get(l2, l2 + mid))
        low = mid;
      else
        high = mid;
    }
    return (low);
  }
};

template <class Type>
class WeightedUnionFind {
public:
  WeightedUnionFind() = default;
  /// @brief 重み付き Union-Find 木を構築します。
  /// @param n 要素数
  explicit WeightedUnionFind(size_t n)
      : m_parentsOrSize(n, -1), m_diffWeights(n) {}
  /// @brief 頂点 i の root のインデックスを返します。
  /// @param i 調べる頂点のインデックス
  /// @return 頂点 i の root のインデックス
  int find(int i) {
    if (m_parentsOrSize[i] < 0)
      return i;
    const int root = find(m_parentsOrSize[i]);
    m_diffWeights[i] += m_diffWeights[m_parentsOrSize[i]];
    // 経路圧縮
    return (m_parentsOrSize[i] = root);
  }
  /// @brief a のグループと b のグループを統合します。
  /// @param a 一方のインデックス
  /// @param b 他方のインデックス
  /// @param w (b の重み) - (a の重み)
  void merge(int a, int b, Type w) {
    w += weight(a);
    w -= weight(b);
    a = find(a);
    b = find(b);
    if (a != b) {
      // union by size (小さいほうが子になる）
      if (-m_parentsOrSize[a] < -m_parentsOrSize[b]) {
        swap(a, b);
        w = -w;
      }
      m_parentsOrSize[a] += m_parentsOrSize[b];
      m_parentsOrSize[b] = a;
      m_diffWeights[b] = w;
    }
  }
  /// @brief (b の重み) - (a の重み) を返します。
  /// @param a 一方のインデックス
  /// @param b 他方のインデックス
  /// @remark a と b が同じグループに属さない場合の結果は不定です。
  /// @return (b の重み) - (a の重み)
  Type diff(int a, int b) {
    return (weight(b) - weight(a));
  }
  /// @brief a と b が同じグループに属すかを返します。
  /// @param a 一方のインデックス
  /// @param b 他方のインデックス
  /// @return a と b が同じグループに属す場合 true, それ以外の場合は false
  bool connected(int a, int b) {
    return (find(a) == find(b));
  }
  /// @brief i が属するグループの要素数を返します。
  /// @param i インデックス
  /// @return i が属するグループの要素数
  int size(int i) {
    return -m_parentsOrSize[find(i)];
  }

private:
  // m_parentsOrSize[i] は i の 親,
  // ただし root の場合は (-1 * そのグループに属する要素数)
  vector<int> m_parentsOrSize;
  // 重み
  vector<Type> m_diffWeights;
  Type weight(int i) {
    find(i); // 経路圧縮
    return m_diffWeights[i];
  }
};

class DirectedGraph {
public:
  struct Edge {
    int to, cost;
  };
  const int N;
  vector<vector<Edge>> g;
  DirectedGraph(int _n) : g(_n), N(_n) {}
  void add(int s, int t, int cost) {
    g[s].push_back({t, cost});
  }
  struct warshallfloyd_return {
    vector<vector<int>> dist, next;
  };
  // O(V^3)
  warshallfloyd_return warshallfloyd() {
    vector<vector<int>> dist(N, vector<int>(N, INF)), next(N, vector<int>(N, INF));
    for (int i = 0; i < N; i++)
      dist[i][i] = 0;
    for (int i = 0; i < N; i++)
      for (int j = 0; j < N; j++)
        next[i][j] = j;
    for (int i = 0; i < N; i++)
      for (auto &j : g[i])
        chmin(dist[i][j.to], j.cost);
    for (int k = 0; k < N; k++)
      for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
          if (chmin(dist[i][j], dist[i][k] + dist[k][j]))
            next[i][j] = next[i][k];
    return {dist, next};
  }
  // O(E+VlogV)
  vector<int> dijkstra(int s) {
    vector<int> d(N, INF);
    d[s] = 0;
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> que;
    que.push(make_pair(0, s));
    while (!que.empty()) {
      pair<int, int> p = que.top();
      que.pop();
      int v = p.second;
      if (d[v] < p.first)
        continue;
      for (auto e : g[v]) {
        if (d[e.to] > d[v] + e.cost) {
          d[e.to] = d[v] + e.cost;
          que.push(make_pair(d[e.to], e.to));
        }
      }
    }
    return d;
  }
  struct bellmanford_return {
    vector<int> path, distances;
    bool hascycle;
  };
  // O(V*E)
  // https://zenn.dev/reputeless/books/standard-cpp-for-competitive-programming/viewer/bellman-ford
  bellmanford_return bellmanford_SPFA(int st, int ed) {
    vector<int> counts(g.size()), distances(g.size(), INF), path;
    vector<bool> inqueue(g.size());
    queue<int> q;
    vector<int> p(g.size(), -1);
    distances[st] = 0;
    q.push(st);
    inqueue[st] = true;
    while (!q.empty()) {
      const int from = q.front();
      q.pop();
      inqueue[from] = false;
      for (const auto &edge : g[from]) {
        const long long d = (distances[from] + edge.cost);
        if (d < distances[edge.to]) {
          distances[edge.to] = d;
          p[edge.to] = from;
          if (!inqueue[edge.to]) {
            q.push(edge.to);
            inqueue[edge.to] = true;
            ++counts[edge.to];
            if (g.size() < counts[edge.to])
              return {vector<int>(), vector<int>(), true};
          }
        }
      }
    }
    if (distances[ed] != INF) {
      for (int i = ed; i != -1; i = p[i])
        path.push_back(i);
      reverse(path.begin(), path.end());
    }
    return {path, distances, false};
  }
  // O(V+E)
  vector<int> topologicalSort() {
    vector<int> d, ind(N);
    for (int i = 0; i < N; i++)
      for (auto e : g[i])
        ind[e.to]++;
    queue<int> que;
    for (int i = 0; i < N; i++)
      if (ind[i] == 0)
        que.push(i);
    while (!que.empty()) {
      int now = que.front();
      d.push_back(now);
      que.pop();
      for (auto e : g[now]) {
        ind[e.to]--;
        if (ind[e.to] == 0)
          que.push(e.to);
      }
    }
    return d;
  }
};

class UndirectedGraph {
public:
  int n;
  vector<tuple<int, int, int>> g;
  UndirectedGraph(int _n) {
    n = _n;
  }
  void add(int u, int v, int c) {
    g.push_back({u, v, c});
  }
  // O(ElogV)
  vector<vector<int>> kruskal() {
    UnionFind uf(n);
    vector<vector<int>> res(n);
    sort(g.begin(), g.end(), [](auto &l, auto &r) { return get<2>(l) < get<2>(r); });
    D(g);
    for (auto &[a, b, cost] : g) {
      if (uf.merge(a, b)) {
        res[a].push_back(b);
        res[b].push_back(a);
      }
    }
    return res;
  }
};

class Range {
  int m_value;
  const int m_end;
  const int m_stride;

public:
  Range(int begin, int end, int stride) : m_value(begin), m_end(end), m_stride(stride) {}
  const int &value() const { return m_value; }
  Range begin() const { return *this; }
  int end() const { return m_end; }
  bool operator!=(const int &value) const {
    return m_stride > 0 ? m_value < value : m_value > value;
  }
  void operator++() { m_value += m_stride; }
  const int &operator*() const { return m_value; }
};
Range range(int end) {
  return {0LL, end, 1LL};
}
Range range(int begin, int end) {
  return {begin, end, 1LL};
}
Range range(int begin, int end, int stride) {
  return {begin, end, stride};
}

void solve();

signed main() {
  cin.tie(0)->sync_with_stdio(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(16);
  solve();
}

struct Ptr{
  int r,c;
  int dir;
  int mem;
};

void solve() {
  int r,c;cin>>r>>c;
  vector<vector<char>> s(r,vector<char>(c));cin>>s;

  queue<Ptr> que;
  set<tuple<int,int,int,int>> cache;

  {
    Ptr init;
    init.r=0;
    init.c=0;
    init.mem=0;
    init.dir = 0;
    que.push(init);
  }

  while(not que.empty()){ // exec and move
    auto q = que.front();
    que.pop();

    if(cache.find({q.r,q.c,q.mem,q.dir}) != cache.end()){
      continue;
    }
    cache.insert({q.r,q.c,q.mem,q.dir});

    if(s[q.r][q.c] == '<'){
      q.dir=2;
    }
    if(s[q.r][q.c] == '>'){
      q.dir=0;
    }
    if(s[q.r][q.c] == '^'){
      q.dir=3;
    }
    if(s[q.r][q.c] == 'v'){
      q.dir=1;
    }
    if(s[q.r][q.c] == '_'){
      if(q.mem == 0){
        q.dir=0;
      }else{
        q.dir=2;
      }
    }
    if(s[q.r][q.c] == '|'){
      if(q.mem == 0){
        q.dir=1;
      }else{
        q.dir=3;
      }
    }
    if(s[q.r][q.c] == '.'){

    }
    if(s[q.r][q.c] == '@'){
      cout<<"YES\n";
      return;
    }
    if('0' <= s[q.r][q.c] and s[q.r][q.c] <= '9'){
      q.mem = s[q.r][q.c]-'0';
    }
    if(s[q.r][q.c] == '+'){
      if(++q.mem == 16)
        q.mem=0;
    }
    if(s[q.r][q.c] == '-'){
      if(--q.mem == -1)
        q.mem=15;
    }

    if(s[q.r][q.c] == '?'){
      int mem;
      q.dir=0;
      mem=q.c;
      if(++q.c == c)
        q.c=0;
      que.push(q);
      q.c=mem;

      q.dir=1;
      mem=q.r;
      if(++q.r == r)
        q.r=0;
      que.push(q);
      q.r=mem;

      q.dir=2;
      mem=q.c;
      if(--q.c == -1)
        q.c=c-1;
      que.push(q);
      q.c=mem;

      q.dir=3;
      mem=q.r;
      if(--q.r == -1)
        q.r=r-1;
      que.push(q);

      continue;
    }

    if(q.dir==0){
      if(++q.c == c)
        q.c=0;
    }
    if(q.dir==1){
      if(++q.r == r)
        q.r=0;
    }
    if(q.dir==2){
      if(--q.c == -1)
        q.c=c-1;
    }
    if(q.dir==3){
      if(--q.r == -1)
        q.r=r-1;
    }
    que.push(q);
  }
  cout<<"NO"<<endl;
}
accuracy: 1
time_ms: 10
memory_kb: 5428
final_rank: 8

code_snippet: #define _USE_MATH_DEFINES
#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
#include<string>
#include<iomanip>
#include<numeric>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<random>
#include<bitset>
#include<cassert>
using namespace std;
typedef long long ll;
const int mod=998244353;
const int dx[]={1,0,0,-1},dy[]={0,1,-1,0};
int r,c;
string s[20];
struct state{
	int x=0,y=0,mem=0,dir=1;
};
bool end(state st){
	return s[st.x][st.y]=='@';
}
vector<state>next(state st){
	vector<state>res;
	if(s[st.x][st.y]=='<'){
		st.dir=2;
		res.push_back(st);
	}else if(s[st.x][st.y]=='>'){
		st.dir=1;
		res.push_back(st);
	}else if(s[st.x][st.y]=='^'){
		st.dir=3;
		res.push_back(st);
	}else if(s[st.x][st.y]=='v'){
		st.dir=0;
		res.push_back(st);
	}else if(s[st.x][st.y]=='_'){
		st.dir=(st.mem==0?1:2);
		res.push_back(st);
	}else if(s[st.x][st.y]=='|'){
		st.dir=(st.mem==0?0:3);
		res.push_back(st);
	}else if(s[st.x][st.y]=='?'){
		for(int i=0;i<4;i++){
			st.dir=i;
			res.push_back(st);
		}
	}else if(s[st.x][st.y]=='.')
		res.push_back(st);
	else if('0'<=s[st.x][st.y]&&s[st.x][st.y]<='9'){
		st.mem=s[st.x][st.y]-'0';
		res.push_back(st);
	}else if(s[st.x][st.y]=='+'){
		st.mem=(st.mem==15?0:st.mem+1);
		res.push_back(st);
	}else if(s[st.x][st.y]=='-'){
		st.mem=(st.mem==0?15:st.mem-1);
		res.push_back(st);
	}
	for(auto&e:res){
		e.x+=dx[e.dir];
		if(e.x==r)
			e.x=0;
		else if(e.x==-1)
			e.x=r-1;
		e.y+=dy[e.dir];
		if(e.y==c)
			e.y=0;
		else if(e.y==-1)
			e.y=c-1;
	}
	return res;
}
bool operator<(state s1,state s2){
	return tie(s1.x,s1.y,s1.mem,s1.dir)<tie(s2.x,s2.y,s2.mem,s2.dir);
}
int main(){
	cin>>r>>c;
	for(int i=0;i<r;i++)
		cin>>s[i];
	state fst;
	queue<state>que;
	set<state>used;
	que.push(fst);
	used.insert(fst);
	while(que.size()){
 		state st=que.front();
		que.pop();
		if(end(st)){
			cout<<"YES"<<endl;
			return 0;
		}
		auto vec=next(st);
		for(auto&e:vec){
			if(!used.count(e)){
				que.push(e);
				used.insert(e);
			}
		}
	}
	cout<<"NO"<<endl;
}
accuracy: 1
time_ms: 10
memory_kb: 4888
final_rank: 7

code_snippet: #include<iostream>
#include<string>
#include<algorithm>    
#include<cmath>
#include<ctime>
#include<map>
#include<vector>
#include<math.h>
#include<stdio.h>
#include<stack>
#include<queue>
#include<tuple>
#include<cassert>
#include<set>
#include<bitset>
#include<functional>
#include <fstream>
//#include<bits/stdc++.h>
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#define rep(i, x) for(ll i = 0; i < x; i++)
#define rep2(i, x) for(ll i = 1; i <= x; i++)
#define all(a) (a).begin(),(a).end()
#define puts(x) cout << (x) << "\n"
using ll = long long;
using ld = long double;
using namespace std;
const ll INF = 10000000000000000;
const int intINF = 1000000000;
const ll mod = 1000000007;
const ll MOD = 998244353;
const ld pi = 3.141592653589793238;

bool isprime(int p) {
	if (p == 1) return false;
	for (int i = 2; i < p; i++) {
		if (p % i == 0) return false;
	}
	return true;
}
ll gcd(ll a, ll b) {
	if (a < b)swap(a, b);
	if (a % b == 0)return b;
	return gcd(b, a % b);
}
ll lcm(ll a, ll b) {
	return a / gcd(a, b) * b;
}
ll keta(ll n) {
	ll res = 0;
	while (n >= 1) {
		res += n % 10; n /= 10;
	}
	return res;
}
ll modpow(ll x, ll y) {
	ll res = 1;
	while (y) {
		if (y % 2) { res *= x; res %= mod; }
		x = x * x % mod; y /= 2;
	}
	return res;
}
ll nCk(ll n, ll k) {
	ll a = 1, b = 1;
	for (int h = n - k + 1; h <= n; h++) { a *= h; a %= mod; }
	for (int h = 1; h <= k; h++) { b *= h; b %= mod; }
	return a * modpow(b, mod - 2) % mod;
}
//printf("%.10f\n", n);
typedef pair <ll, ll> P;
ll dx[4] = { 1, 0, -1, 0 }, dy[4] = { 0, 1, 0, -1 };
struct edge { ll to, cost; };
struct status {
	ll x;
	ll y;
	char mk;
	ll cost;

	bool operator<(const status& rhs) const { return cost < rhs.cost; };
	bool operator>(const status& rhs) const { return cost > rhs.cost; };
};


char maze[22][22];
signed main() {
	ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	//cout << fixed << setprecision(15);

	//input
	ll n, m; cin >> n >> m;
	rep(i, n) {
		rep(j, m) {
			cin >> maze[i][j];
		}
	}
	queue<status> que; que.push({ 0,0,'R',0 });
	ll cnt = 0;
	while (que.size()) {
		cnt++;
		if (cnt == 300000) { break; }
		status q = que.front(); que.pop();
      //cout<<q.x<<' '<<q.y<<' '<<q.mk<<' '<<q.cost<<endl;
		if (maze[q.x][q.y] == '<') { que.push({ q.x, (q.y + m - 1) % m,'L', q.cost }); }
		if (maze[q.x][q.y] == '>') { que.push({ q.x, (q.y + 1) % m,'R', q.cost }); }
		if (maze[q.x][q.y] == '^') { que.push({ (q.x + n - 1) % n, q.y,'U', q.cost }); }
		if (maze[q.x][q.y] == 'v') { que.push({ (q.x + 1) % n, q.y,'D', q.cost }); }
		if (maze[q.x][q.y] == '_' && q.cost == 0) { que.push({ q.x, (q.y + 1) % m,'R', q.cost }); }
		if (maze[q.x][q.y] == '_' && q.cost != 0) { que.push({ q.x, (q.y + m - 1) % m,'L', q.cost }); }
		if (maze[q.x][q.y] == '|' && q.cost == 0) { que.push({ (q.x + 1) % n, q.y,'D', q.cost }); }
		if (maze[q.x][q.y] == '|' && q.cost != 0) { que.push({ (q.x + n - 1) % n, q.y,'U', q.cost }); }
		if (maze[q.x][q.y] == '?') {
			que.push({ q.x, (q.y + m - 1) % m,'L', q.cost }); que.push({ q.x, (q.y + 1) % m,'R', q.cost });
			que.push({ (q.x + n - 1) % n, q.y,'U', q.cost }); que.push({ (q.x + 1) % n, q.y,'D', q.cost });
		}
		if (maze[q.x][q.y] == '.') {
			if (q.mk == 'L') { que.push({ q.x, (q.y + m - 1) % m,'L', q.cost }); }
			if (q.mk == 'R') { que.push({ q.x, (q.y + 1) % m,'R', q.cost }); }
			if (q.mk == 'U') { que.push({ (q.x + n - 1) % n, q.y,'U', q.cost }); }
			if (q.mk == 'D') { que.push({ (q.x + 1) % n, q.y,'D', q.cost }); }
		}
		if (maze[q.x][q.y] == '@') { cout << "YES\n"; return 0; }
		if (maze[q.x][q.y] == '0') {
			if (q.mk == 'L') { que.push({ q.x, (q.y + m - 1) % m,'L', 0 }); }
			if (q.mk == 'R') { que.push({ q.x, (q.y + 1) % m,'R', 0 }); }
			if (q.mk == 'U') { que.push({ (q.x + n - 1) % n, q.y,'U', 0 }); }
			if (q.mk == 'D') { que.push({ (q.x + 1) % n, q.y,'D', 0 }); }
		}
		if (maze[q.x][q.y] == '1') {
			if (q.mk == 'L') { que.push({ q.x, (q.y + m - 1) % m,'L', 1 }); }
			if (q.mk == 'R') { que.push({ q.x, (q.y + 1) % m,'R', 1 }); }
			if (q.mk == 'U') { que.push({ (q.x + n - 1) % n, q.y,'U', 1 }); }
			if (q.mk == 'D') { que.push({ (q.x + 1) % n, q.y,'D', 1 }); }
		}
		if (maze[q.x][q.y] == '2') {
			if (q.mk == 'L') { que.push({ q.x, (q.y + m - 1) % m,'L', 2 }); }
			if (q.mk == 'R') { que.push({ q.x, (q.y + 1) % m,'R', 2 }); }
			if (q.mk == 'U') { que.push({ (q.x + n - 1) % n, q.y,'U', 2 }); }
			if (q.mk == 'D') { que.push({ (q.x + 1) % n, q.y,'D', 2 }); }
		}
		if (maze[q.x][q.y] == '3') {
			if (q.mk == 'L') { que.push({ q.x, (q.y + m - 1) % m,'L', 3 }); }
			if (q.mk == 'R') { que.push({ q.x, (q.y + 1) % m,'R', 3 }); }
			if (q.mk == 'U') { que.push({ (q.x + n - 1) % n, q.y,'U', 3 }); }
			if (q.mk == 'D') { que.push({ (q.x + 1) % n, q.y,'D', 3 }); }
		}
		if (maze[q.x][q.y] == '4') {
			if (q.mk == 'L') { que.push({ q.x, (q.y + m - 1) % m,'L', 4 }); }
			if (q.mk == 'R') { que.push({ q.x, (q.y + 1) % m,'R', 4 }); }
			if (q.mk == 'U') { que.push({ (q.x + n - 1) % n, q.y,'U', 4 }); }
			if (q.mk == 'D') { que.push({ (q.x + 1) % n, q.y,'D', 4 }); }
		}
		if (maze[q.x][q.y] == '5') {
			if (q.mk == 'L') { que.push({ q.x, (q.y + m - 1) % m,'L', 5 }); }
			if (q.mk == 'R') { que.push({ q.x, (q.y + 1) % m,'R', 5 }); }
			if (q.mk == 'U') { que.push({ (q.x + n - 1) % n, q.y,'U', 5 }); }
			if (q.mk == 'D') { que.push({ (q.x + 1) % n, q.y,'D', 5 }); }
		}
		if (maze[q.x][q.y] == '6') {
			if (q.mk == 'L') { que.push({ q.x, (q.y + m - 1) % m,'L', 6 }); }
			if (q.mk == 'R') { que.push({ q.x, (q.y + 1) % m,'R', 6 }); }
			if (q.mk == 'U') { que.push({ (q.x + n - 1) % n, q.y,'U', 6 }); }
			if (q.mk == 'D') { que.push({ (q.x + 1) % n, q.y,'D', 6 }); }
		}
		if (maze[q.x][q.y] == '7') {
			if (q.mk == 'L') { que.push({ q.x, (q.y + m - 1) % m,'L', 7 }); }
			if (q.mk == 'R') { que.push({ q.x, (q.y + 1) % m,'R', 7 }); }
			if (q.mk == 'U') { que.push({ (q.x + n - 1) % n, q.y,'U', 7 }); }
			if (q.mk == 'D') { que.push({ (q.x + 1) % n, q.y,'D', 7 }); }
		}
		if (maze[q.x][q.y] == '8') {
			if (q.mk == 'L') { que.push({ q.x, (q.y + m - 1) % m,'L', 8 }); }
			if (q.mk == 'R') { que.push({ q.x, (q.y + 1) % m,'R', 8 }); }
			if (q.mk == 'U') { que.push({ (q.x + n - 1) % n, q.y,'U', 8 }); }
			if (q.mk == 'D') { que.push({ (q.x + 1) % n, q.y,'D', 8 }); }
		}
		if (maze[q.x][q.y] == '9') {
			if (q.mk == 'L') { que.push({ q.x, (q.y + m - 1) % m,'L', 9 }); }
			if (q.mk == 'R') { que.push({ q.x, (q.y + 1) % m,'R', 9 }); }
			if (q.mk == 'U') { que.push({ (q.x + n - 1) % n, q.y,'U', 9 }); }
			if (q.mk == 'D') { que.push({ (q.x + 1) % n, q.y,'D', 9 }); }
		}
		if (maze[q.x][q.y] == '+') {
			if (q.mk == 'L') { que.push({ q.x, (q.y + m - 1) % m,'L', (q.cost + 1) % 16 }); }
			if (q.mk == 'R') { que.push({ q.x, (q.y + 1) % m,'R', (q.cost + 1) % 16 }); }
			if (q.mk == 'U') { que.push({ (q.x + n - 1) % n, q.y,'U', (q.cost + 1) % 16 }); }
			if (q.mk == 'D') { que.push({ (q.x + 1) % n, q.y,'D', (q.cost + 1) % 16 }); }
		}
		if (maze[q.x][q.y] == '-') {
			if (q.mk == 'L') { que.push({ q.x, (q.y + m - 1) % m,'L', (q.cost + 15) % 16 }); }
			if (q.mk == 'R') { que.push({ q.x, (q.y + 1) % m,'R', (q.cost + 15) % 16 }); }
			if (q.mk == 'U') { que.push({ (q.x + n - 1) % n, q.y,'U', (q.cost + 15) % 16 }); }
			if (q.mk == 'D') { que.push({ (q.x + 1) % n, q.y,'D', (q.cost + 15) % 16 }); }
		}
	}
	cout << "NO\n";
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 31656
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
  
#define REP(i,a,b) for(int i=(a);i<(b);++i)
#define rep(i,n) REP(i,0,n)
#define INF (1<<30)
#define INFLL (1LL<<62LL)
  
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
  
int dx[8] = {0, 1, 0, -1, 1, -1, 1, -1};
int dy[8] = {1, 0, -1, 0, 1, -1, -1, 1};
  
#define DOWN   0
#define RIGHT 1
#define UP       2
#define LEFT   3
  
struct State {
    int x, y;
    int mem;
    int dir;
  
    State() :
            x(0),
            y(0),
            mem(0),
            dir(RIGHT) {}
  
    State(int x, int y, int mem, int dir) :
            x(x),
            y(y),
            mem(mem),
            dir(dir) {}
  
    bool operator<(const State & rhs) const {
        if (x == rhs.x && y == rhs.y && mem == rhs.mem) return dir < rhs.dir;
        if (x == rhs.x && y == rhs.y) return mem < rhs.mem;
        if (x == rhs.x) return y < rhs.y;
        return x < rhs.x;
    }
};
  
int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);
    int R, C;
    cin >> R >> C;
    vector<string> prog(R);
    rep(i, R) cin >> prog[i];
  
    set<State> visited;
    queue<State> Q;
    ll ok = false;
  
    Q.push(State());
    while (!Q.empty()) {
        State st = Q.front();
        Q.pop();
  
        st.x = (st.x + C) % C;
        st.y = (st.y + R) % R;
  
        if (visited.find(st) != visited.end())
            continue;
          
        visited.insert(st);
  
        char p;
        p = prog[st.y][st.x];
  
        if (p == '@') {
            ok = true;
            break;
        }
  
        switch (p) {
            case '0'...'9':
                st.mem = p - '0';
                break;
            case '_':
                if (st.mem == 0) st.dir = RIGHT;
                else st.dir = LEFT;
                break;
            case '|':
                if (st.mem == 0) st.dir = DOWN;
                else st.dir = UP;
                break;
            case '+':
                st.mem = (st.mem + 1) % 16;
                break;
            case '-':
                st.mem = st.mem - 1;
                if (st.mem < 0) st.mem += 16;
                break;
            case '^':
                st.dir = UP;
                break;
            case 'v':
                st.dir = DOWN;
                break;
            case '<':
                st.dir = LEFT;
                break;
            case '>':
                st.dir = RIGHT;
                break;
        }
  
        if (p != '?') {
            Q.push(State(st.x + dx[st.dir], st.y + dy[st.dir], st.mem, st.dir));
        } else {
            Q.push(State(st.x + dx[LEFT],     st.y + dy[LEFT],   st.mem, LEFT));
            Q.push(State(st.x + dx[RIGHT],   st.y + dy[RIGHT], st.mem, RIGHT));
            Q.push(State(st.x + dx[UP],         st.y + dy[UP],       st.mem, UP));
            Q.push(State(st.x + dx[DOWN],     st.y + dy[DOWN],   st.mem, DOWN));
        }
    }
      
    if (ok) cout << "YES" << endl;
    else cout << "NO" << endl;
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 4772
final_rank: 5

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

#define DUMP(x) cerr << #x << "=" << x << endl
#define DUMP2(x, y) cerr<<"("<<#x<<", "<<#y<<") = ("<<x<<", "<<y<<")"<< endl
#define BINARY(x) static_cast<bitset<16> >(x)

#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define REP(i,m,n) for (int i=m;i<(int)(n);i++)

#define in_range(x, y, w, h) (0<=(int)(x) && (int)(x)<(int)(w) && 0<=(int)(y) && (int)(y)<(int)(h))
#define ALL(a) (a).begin(),(a).end()

typedef long long ll;
const int INF   = 1e9;
const ll  INFLL = 1e18;
typedef pair<int, int> PII;
int dx[4]={0, -1, 1, 0}, dy[4]={-1, 0, 0, 1};

int R, C;

const int UP    = 0;
const int LEFT  = 1;
const int RIGHT = 2;
const int DOWN  = 3;

struct State {
    int x, y, memory, direction;
    bool operator<(const State &rhs) const 
    {
        if (x == rhs.x) {
           if (y == rhs.y) {
               if (memory == rhs.memory) return direction < rhs.direction;
               else return memory < rhs.memory;
           } else {
               return y < rhs.y;
           }
        } else {
            return x < rhs.x;
        }
    }
    
};

PII move(int x, int y, int dir)
{
    PII res(x + dx[dir], y + dy[dir]);
    res.first = (res.first + C) % C;
    res.second = (res.second + R) % R;
    return res;
}

int increment(int x)
{
    return (x+1)%16;
}

int decrement(int x)
{
    return (x - 1 + 16) % 16;
}

bool solve(vector<string> P)
{
   map<State, bool> vis;
    queue<State> Q;
    Q.push({0, 0, 0, RIGHT});
    vis[State({0, 0, 0, RIGHT})] = true;

    while (Q.size()) {
        State s = Q.front(); Q.pop();
        vector<State> ns;

#ifdef DEBUG
        cerr << s.x << " " << s.y << " " << s.memory << " " << "<^>v"[s.direction] << endl;
#endif

        switch (P[s.y][s.x]) {
            case '<':
                {
                    PII npos = move(s.x, s.y, LEFT);
                    ns.push_back({npos.first, npos.second, s.memory, LEFT});
                }
                break;
            case '>':
                {
                    PII npos = move(s.x, s.y, RIGHT);
                    ns.push_back({npos.first, npos.second, s.memory, RIGHT});
                }
                break;
            case '^':
                {
                    PII npos = move(s.x, s.y, UP);
                    ns.push_back({npos.first, npos.second, s.memory, UP});
                }
                break;
            case 'v':
                {
                    PII npos = move(s.x, s.y, DOWN);
                    ns.push_back({npos.first, npos.second, s.memory, DOWN});
                }
                break;
            case '_':
                {
                    int ndir = (!s.memory ? RIGHT : LEFT);
                    PII npos = move(s.x, s.y, ndir);
                    ns.push_back({npos.first, npos.second, s.memory, ndir});
                }
                break;
            case '|':
                {
                    int ndir = (!s.memory ? DOWN : UP);
                    PII npos = move(s.x, s.y, ndir);
                    ns.push_back({npos.first, npos.second, s.memory, ndir});
                }
                break;
            case '?':
                rep(i, 4) {
                    int ndir = i;
                    PII npos = move(s.x, s.y, ndir);
                    ns.push_back({npos.first, npos.second, s.memory, ndir});
                }
                break;
            case '.':
                {
                    int ndir = s.direction;
                    PII npos = move(s.x, s.y, ndir);
                    ns.push_back({npos.first, npos.second, s.memory, ndir});
                }
                break;
            case '@':
                return true;
            case '+':
                {
                    int nmemory = increment(s.memory);
                    PII npos = move(s.x, s.y, s.direction);
                    ns.push_back({npos.first, npos.second, nmemory, s.direction});
                }
                break;
            case '-':
                {
                    int nmemory = decrement(s.memory);
                    PII npos = move(s.x, s.y, s.direction);
                    ns.push_back({npos.first, npos.second, nmemory, s.direction});
                }
                break;
            default:
                {
                    int nmemory = (P[s.y][s.x] - '0');
                    PII npos = move(s.x, s.y, s.direction);
                    ns.push_back({npos.first, npos.second, nmemory, s.direction});
                }
                break;
        }

        for (State m : ns) {
            if (!vis[m]) {
                vis[m] = true;
                Q.push(m);
            }
        }
    }
    return false;
}

int main()
{
    ios::sync_with_stdio(false);

    cin >> R >> C;
    vector<string> P(R);
    rep(i, R) cin >> P[i];
    cout << (solve(P) ? "YES" : "NO") << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 4852
final_rank: 6

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define LOG(...) fprintf(stderr,__VA_ARGS__)
//#define LOG(...)
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);++i)
#define REP(i,n) for(int i=0;i<(int)(n);++i)
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort(ALL(c))
#define RSORT(c) sort(RALL(c))

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

// right, down, left, up
const int dx[] = {1,0,-1,0}, dy[] = {0,1,0,-1};

int H, W;
char Prog[20][20];

bool G[20][20][4][16]; // y, x, cour, memory

bool run(int x, int y, int cour, int mem) {
    do {
        G[y][x][cour][mem] = true;
        switch (Prog[y][x]) {
        case '<':
            cour = 2;
            break;
        case '>':
            cour = 0;
            break;
        case '^':
            cour = 3;
            break;
        case 'v':
            cour = 1;
            break;
        case '_':
            if (mem == 0) {
                cour = 0;
            } else {
                cour = 2;
            }
            break;
        case '|':
            if (mem == 0) {
                cour = 1;
            } else {
                cour = 3;
            }
            break;
        case '?':
            REP(i, 4) {
                int sx = x + dx[i], sy = y + dy[i];
                if (sx < 0)  sx = W-1;
                if (sx >= W) sx = 0;
                if (sy < 0)  sy = H-1;
                if (sy >= H) sy = 0;
                if (run(sx, sy, i, mem)) return true;
            }
            return false;
        case '.':
            break;
        case '@':
            return true;
        case '+':
            if (mem == 15) {
                mem = 0;
            } else {
                mem++;
            }
            break;
        case '-':
            if (mem == 0) {
                mem = 15;
            } else {
                mem--;
            }
            break;
        default: // number
            mem = Prog[y][x] - '0';
        }

        x += dx[cour];
        y += dy[cour];
        if (x < 0)  x = W-1;
        if (x >= W) x = 0;
        if (y < 0)  y = H-1;
        if (y >= H) y = 0;

//        LOG("%02d\n", mem);
//        REP(sy, H) {
//            REP(sx, W) {
//                if (sx == x && sy == y) {
//                    LOG("#");
//                } else {
//                    LOG("%c", Prog[sy][sx]);
//                }
//            }
//            LOG("\n");
//        }
//        getchar();
    } while (!G[y][x][cour][mem]);

    return false;
}

int main() {
    cin >> H >> W;
    REP(y, H) REP(x, W) {
        cin >> Prog[y][x];
    }
    cout << (run(0, 0, 0, 0) ? "YES" : "NO") << endl;
}
accuracy: 0.5833333333333334
time_ms: 10
memory_kb: 9272
final_rank: 13

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
#include <iterator>
#include<queue>
#include <functional>
#include <string>
#include <numeric>
using namespace std;
#define REP(i,n) for(int i=0;i<(n);i++)
#define ALL(v) v.begin(),v.end()
using namespace std;
const int dx[4] = { -1, 1, 0, 0 };
const int dy[4] = { 0, 0, -1, 1 };
struct data
{
	bool memo[20][20][16][4];
	data(){
		REP(i, 20)
			REP(j, 20)
			REP(k, 16)
			REP(l, 4)
			memo[i][j][k][l] = false;
	}
};
int R=0, C=0;
bool a(int ax, int ay, vector<string> Fi,int Memory, int Muki,data aa){
	ax=(ax+C)% C;ay=(ay+R) % R;
	if (aa.memo[ax][ay][Memory][Muki])return false;
	aa.memo[ax][ay][Memory][Muki] = true;
	switch (Fi[ay][ax]){
	case '<':Muki = 0; return a(ax + dx[Muki], ay + dy[Muki], Fi, Memory, Muki,aa);
	case '>':Muki = 1;; return a(ax + dx[Muki], ay + dy[Muki], Fi, Memory, Muki, aa);
	case '^':Muki = 2; return a(ax + dx[Muki], ay + dy[Muki], Fi, Memory, Muki, aa);
	case 'v':Muki = 3; return a(ax + dx[Muki], ay + dy[Muki], Fi, Memory, Muki, aa);
	case '_':Muki = Memory ? 0 : 1; return a(ax + dx[Muki], ay + dy[Muki], Fi, Memory, Muki, aa);
	case '|':Muki = Memory ? 2 : 3; return a(ax + dx[Muki], ay + dy[Muki], Fi, Memory, Muki, aa);
	case '?': return a(ax + dx[0], ay + dy[0], Fi, Memory, 0, aa) || a(ax + dx[1], ay + dy[1], Fi, Memory, 1, aa) || a(ax + dx[2], ay + dy[2], Fi, Memory, 2, aa) || a(ax + dx[3], ay + dy[3], Fi, Memory, 3, aa);
	case '.':return a(ax + dx[Muki], ay + dy[Muki], Fi,Memory, Muki, aa);
	case '@':return true;
	case '+':return a(ax + dx[Muki], ay + dy[Muki], Fi, (Memory + 1) % 16, Muki, aa);
	case '-':return a(ax + dx[Muki], ay + dy[Muki], Fi, (Memory+15) % 16, Muki, aa);
	default:return a(ax + dx[Muki], ay + dy[Muki], Fi, Fi[ay][ax]-48, Muki, aa);
	}
	return 0;
}

int main(){
	cin >> R >> C;
	vector<string> Field(R);
	REP(i, R){
		string st;
		cin >> Field[i];
	}
	data adata;
	if (a(0, 0, Field, 0, 1,adata)){
		cout << "YES" << endl;
	}
	else{
		cout << "NO" << endl;
	}
		
	return 0;
}
accuracy: 0.5833333333333334
time_ms: 10
memory_kb: 9456
final_rank: 14

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

const int pos[]={1,0,-1,0};
struct state{
	char x,y,p,mem;
	bool operator==(const state &A)const{
		return A.x==x&&A.y==y&&A.p==p&&A.mem==mem;
	}
};

bool check(state A,const vector<string> &code,int r,int c,vector<state> &visited){
  char op=code[A.y][A.x];
  while(op!='@'){
  	if(find(visited.begin(),visited.end(),A)!=visited.end())return false;
  	visited.push_back(A);
  	op=code[A.y][A.x];
  	//cerr<<(int)A.x<<","<<(int)A.y<<endl;
  	if(op=='>')A.p=0;
  	if(op=='v')A.p=1;
  	if(op=='<')A.p=2;
  	if(op=='^')A.p=3;
  	if(op=='_')A.p=(A.mem)?2:0;
  	if(op=='|')A.p=(A.mem)?3:1;
   	if('0'<=op&&op<='9')A.mem=op-'0';
   	if(op=='+')A.mem=(A.mem+1)%16;
   	if(op=='-')A.mem=(A.mem+15)%16;
   	if(op=='?'){
   		bool f=false;
   		for(int i=0;i<4;++i){
   			state tmp=A;
   			tmp.p=i;
   			tmp.x=(tmp.x+pos[tmp.p]+c)%c;tmp.y=(tmp.y+pos[(tmp.p+3)%4]+r)%r;
   			if(check(tmp,code,r,c,visited))return true;
   		}
   		return false;
   	}
   	
  	A.x=(A.x+pos[A.p]+c)%c;A.y=(A.y+pos[(A.p+3)%4]+r)%r;
  }
  return true;
}

int main(void){
  int r,c;
  cin>>r>>c;
  vector<string> code;
  for(int i=0;i<r;++i){string s;cin>>s;code.push_back(s);}
  state A={0,0,0,0};
  vector<state> visited;
  cout<<(check(A,code,r,c,visited)?"YES":"NO")<<endl;
  return 0;
}
accuracy: 1
time_ms: 590
memory_kb: 2880
final_rank: 11

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

#define rep(i, n) rep2(i, 0, n)
#define rep2(i, m, n) for(int i = m; i < (int)(n); ++i)
#define pb(e) push_back(e)

typedef long long ll;

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

int main()
{
    int r, c;
    string prog[20];
    cin >> r >> c;
    rep(i, r) cin >> prog[i];
    
    int x = 0, y = 0, dir = 0, mem = 0;
    rep(i, 200000000) {
        switch(prog[y][x]) {
            case '<': dir = 2; break;
            case '>': dir = 0; break;
            case '^': dir = 3; break;
            case 'v': dir = 1; break;
            case '_': dir = (mem == 0 ? 0 : 2); break;
            case '|': dir = (mem == 0 ? 1 : 3); break;
            case '?': dir = rand() & 3; break;
            case '.': break;
            case '@': cout << "YES" << endl; return 0;
            case '+': mem = (mem + 1) & 15; break;
            case '-': mem = (mem - 1) & 15; break;
            default:  mem = prog[y][x] - '0';
        }
        x += dx[dir]; y += dy[dir];
        if(x == -1) x = c - 1;
        if(x == c) x = 0;
        if(y == -1) y = r - 1;
        if(y == r) y = 0;
    }
    cout << "NO" << endl;
}
accuracy: 0.4
time_ms: 680
memory_kb: 1208
final_rank: 16

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

#define rep(i, n) rep2(i, 0, n)
#define rep2(i, m, n) for(int i = m; i < (int)(n); ++i)
#define pb(e) push_back(e)

typedef long long ll;

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

int main()
{
    int r, c;
    string prog[20];
    cin >> r >> c;
    rep(i, r) cin >> prog[i];
    
    int x = 0, y = 0, dir = 0, mem = 0;
    rep(i, 10000000) {
        switch(prog[y][x]) {
            case '<': dir = 2; break;
            case '>': dir = 0; break;
            case '^': dir = 3; break;
            case 'v': dir = 1; break;
            case '_': dir = (mem == 0 ? 0 : 2); break;
            case '|': dir = (mem == 0 ? 1 : 3); break;
            case '?': dir = rand() & 3; break;
            case '.': break;
            case '@': cout << "YES" << endl; return 0;
            case '+': mem = (mem + 1) & 15; break;
            case '-': mem = (mem - 1) & 15; break;
            default:  mem = prog[y][x] - '0';
        }
        x += dx[dir]; y += dy[dir];
        if(x == -1) x = c - 1;
        if(x == c) x = 0;
        if(y == -1) y = r - 1;
        if(y == r) y = 0;
    }
    cout << "NO" << endl;
}
accuracy: 0.4
time_ms: 30
memory_kb: 1208
final_rank: 15

code_snippet: #include<stdio.h>
#include<set>
#include<queue>

int dxs[]={1,0,-1,0};
int dys[]={0,-1,0,1};//右、上、左、下の順
int r,c;

struct cur{
	int x,y,arrow;//位置と向き
	int num;//メモリの状態
	bool operator<(const cur& c)const{
		if(x!=c.x)return x<c.x;
		if(y!=c.y)return y<c.y;
		if(arrow!=c.arrow)return arrow<c.arrow;
		return num<c.num;
	}
	cur move(int arrow){
		cur re;
		re.x=(x+dxs[arrow]+c)%c;
		re.y=(y+dys[arrow]+r)%r;
		re.arrow=arrow;
		re.num=num;
		return re;
	}
};


int main(){
	scanf("%d %d",&r,&c);
	char map[22][22];
	int x,y;
	for(int i=0;i<r;i++){
		scanf("%s",map[i]);
	}
	cur c1,nextC;
	c1.x=c1.y=c1.num=c1.arrow=0;
	std::set<cur> memo;
	std::queue<cur> Q;
	memo.insert(c1);
	Q.push(c1);
	bool stop=false;
	while(Q.empty()==false){
		c1=Q.front();
		Q.pop();
		x=c1.x;
		y=c1.y;
		char com=map[y][x];
		if(com=='@'){
			stop=true;//停止
			break;
		}
		if(com=='?'){
			//4方向全て試す
			for(int i=0;i<4;i++){
				nextC=c1.move(i);
				if(memo.find(nextC)==memo.end()){
					memo.insert(nextC);
					Q.push(nextC);
				}
			}
			continue;
		}
		if(com=='<'){
			nextC=c1.move(2);//左
		}else if(com=='>'){
			nextC=c1.move(0);//右	
		}else if(com=='^'){
			nextC=c1.move(1);//上
		}else if(com=='v'){
			nextC=c1.move(3);//下
		}else if(com=='_'){
			if(c1.num==0)nextC=c1.move(0);//0なら右
			else nextC=c1.move(2);
		}else if(com=='|'){
			if(c1.num==0)nextC=c1.move(3);//0なら下
			else nextC=c1.move(1);
		}else if(com=='.'){
			nextC=c1.move(c1.arrow);//そのまま
		}else if('0'<=com&&com<='9'){
			nextC=c1.move(c1.arrow);
			nextC.num=com-'0';
		}else if(com=='+'){
			nextC=c1.move(c1.arrow);
			nextC.num=(c1.num+1)%16;
		}else if(com=='-'){
			nextC=c1.move(c1.arrow);
			nextC.num=(c1.num-1+16)%16;
		}
		if(memo.find(nextC)==memo.end()){
			memo.insert(nextC);
			Q.push(nextC);
		}
	}
	printf("%s\n",stop?"YES":"NO");
}
accuracy: 1
time_ms: 20
memory_kb: 0
final_rank: 1

code_snippet: //template ver1.00
//------------------------------------------

//include
//------------------------------------------
#include <vector>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <bitset>
#include <algorithm>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <complex>

using namespace std;

//conversion
//------------------------------------------
inline int to_int(string s) {int v; istringstream sin(s); sin >> v; return v;}
template<class T> inline string to_str(T x) {ostringstream sout; sout << x; return sout.str();}

//math
//-------------------------------------------
template<class T> inline T sqr(T x) {return x*x;}
template<class T> inline T is_inner(T x, T a, T b) {return a <= x && x < b;}

//typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef long long LL;

//container util
//------------------------------------------
#define ALL(a, n)  (a), (a) + (n)
#define CALL(c)  (c).begin(),(c).end()
#define VADD(v, e) (v).push_back(e)
#define SADD(s, e) (s).insert(e)
#define STADD(s, e) (s).push(e)
#define QADD(q, e) (q).push(e)
#define PQADD(q, e) (q).push(e)
#define STPOP(s, e) typeof((s).top()) e = (s).top(); (s).pop()
#define QPOP(q, e) typeof((q).front()) e = (q).front(); (q).pop()
#define PQPOP(q, e) typeof((q).top()) e = (q).top(); (q).pop()
#define MP make_pair
#define PF(p) (p).first
#define PS(p) (p).second
#define SZ(a) int((a).size())
#define EACH(i, c) for(typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define EXIST(c, e) ((c).find(e) != (c).end())
#define SORT(a, n) sort(ALL(a, n))
#define CSORT(c) sort(CALL(c))
#define RSORT(a, n) sort(ALL(a, n), greater<typeof(a[0])>())
#define CRSORT(c) sort(CALL((c)), greater<typeof(c[0])>())
#define INDEX(a, n, x) find(ALL((a), n), x) - (a)

//repetition
//------------------------------------------
#define FOR(i, a, b) for (int i = (a);i < (b); ++i)
#define RFOR(i, a, b) for (int i = (b) - 1; i >= (a); --i)
#define REP(i, n) FOR(i, 0, n)
#define RREP(i, n) RFOR(i, 0, n)

//IO
//------------------------------------------
#define LF(x) cout << (x) << endl;
#define LF2(x, y) cout << (x) << " " << (y) << endl;
#define LFA(a, n) cout << a[0]; FOR(i, 1, n) {cout << " " << a[i];} cout << endl;
#define LFD(x, w) cout.width = (w); cout << (x) << endl;
#define LFDA(a, n, w) REP(i, n) cout.width = (w); cout << a[i] << endl;
#define LFP(x, w) cout << setprecision((w)); cout << setiosflags(ios::fixed); cout << (x) << endl;
#define LFP2(x, y, w) cout << setprecision((w)); cout << setiosflags(ios::fixed); cout << (x) << " " << (y) << endl;
#define LFPA(a, n, w) cout << setprecision((w)); cout << setiosflags(ios::fixed); cout << a[0]; FOR(i, 1, n) {cout << " " << a[i];} cout << endl;

//constant
//--------------------------------------------
const double EPS = 1e-10;
const double PI  = acos(-1.0);
const int INF = 1e9;
const int DI[] = {0, 1, 0, -1};
const int DJ[] = {1, 0, -1, 0};

//clear memory
//--------------------------------------------
#define CLR(a) memset((a), 0 , sizeof(a))

//debug
//--------------------------------------------
#define DUMP(x)  cerr << #x << " = " << (x) << endl;
#define DEBUG(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl;
#define DUMPA(a, n) cerr << #a << " = {" << a[0]; FOR(i, 1, n) { cout << ", " << a[i]; } cerr << "}" << endl;
#define DEBUGA(a, n) cerr << #a << " = {" << a[0]; FOR(i, 1, n) { cout << ", " << a[i]; } cerr << "} (L" << __LINE__ << ")" << endl;
#define DUMPAA(a, n, m) REP(i, n) {REP(j, m) {cout << a[i][j] << " ";} cout << endl;}
#define DEBUGAA(a, n, m) DUMPAA(a, n, m) cout << "(L" << __LINE__ << ")" << endl;

const int R = 20;
const int C = 20;
const int M = 16;
const int D = 4;

struct T {
	int i, j;
	int m, d;
	
	int toi()
	{
		return i + R * j + R * C * m + R * C * M * d;
	}
	
	bool operator<(const T& t) const
	{
		if (d != t.d) return d < t.d;
		if (m != t.m) return m < t.m;
		if (j != t.j) return j < t.j;
		return i < t.i ;
	}
};


int r, c;
char p[R][C];

vector<T> e[R * C * M * D];
set<T> used;

int f(int x, int y, int m)
{
	return (x + y + m) % m;
}

bool dfs(T t)
{
	if (EXIST(used, t)) return false;
	SADD(used, t);
	if (p[t.i][t.j] == '@') return true;
	EACH(i, e[t.toi()]) if (dfs(*i)) return true;
	return false;
}

void init()
{
}

void solve()
{
	REP(i, R * C * M * D) e[i].clear();
	used.clear();
	REP(i, r) REP(j, c) REP(k, M) REP(l, D) {
		T t = {i, j, k, l};
		if (p[i][j] == '?') {
			REP(d, D) {
				T u = {f(i, DI[d], r), f(j, DJ[d], c), k, d};
				VADD(e[t.toi()], u);
			}
			continue;
		}
		T u;
		switch (p[i][j]) {
		case '<': u.d = 2; break;
		case '>': u.d = 0; break;
		case '^': u.d = 3; break;
		case 'v': u.d = 1; break;
		case '_': u.d = k == 0 ? 0 : 2; break;
		case '|': u.d = k == 0 ? 1 : 3; break;
		default: u.d = l;
		}
		u.m = k;
		if ('0' <= p[i][j] && p[i][j] <= '9') u.m = p[i][j] - '0';
		if (p[i][j] == '+') u.m = f(k, 1, M);
		if (p[i][j] == '-') u.m = f(k, -1, M);
		u.i = f(i, DI[u.d], r);
		u.j = f(j, DJ[u.d], c);
		VADD(e[t.toi()], u);
	}
	T init = {0, 0, 0, 0};
	if (dfs(init)) {
		LF("YES");
	}
	else LF("NO");
}

int main()
{
	init();
	cin >> r >> c;
	REP(i, r) cin >> p[i];
	solve();
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 5200
final_rank: 9

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)n; ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
struct S{
  int x,y,r,m;
  S(int x,int y,int r,int m) :
    x(x),y(y),r(r),m(m) {}
  bool operator < (const S& s) const {
    return (x!=s.x)?(x<s.x):(y!=s.y)?(y<s.y):(r!=s.r)?(r<s.r):(m<s.m);
  }
};
int dx[4] = {1,0,-1,0};
int dy[4] = {0,1,0,-1};

int main(){
  int h,w;
  while(cin>>h>>w){
    vector<string> grid(h);
    REP(i,h)cin>>grid[i];
    queue<S> que;
    set<S> used;
    que.push(S(0,0,0,0));
    while(!que.empty()){
      S s = que.front(); que.pop();
      if(used.find(s)!=used.end()) continue;
      used.insert(s);
      bool all = false;
      bool end = false;
      switch(grid[s.y][s.x]){
        case '<':
          s.r = 2;
          break;
        case '>':
          s.r = 0;
          break;
        case '^':
          s.r = 3;
          break;
        case 'v':
          s.r = 1;
          break;
        case '_':
          s.r = ((s.m)?2:0);
          break;
        case '|':
          s.r = ((s.m)?3:1);
          break;
        case '?':
          all = true;
          break;
        case '.':
          break;
        case '@':
          end = true;
          break;
        case '+':
          s.m = (s.m+1)%16;
          break;
        case '-':
          s.m = (s.m+16-1)%16;
          break;
      }
      if(end){
        cout<<"YES"<<endl;
        goto END;
      }
      if(grid[s.y][s.x]<='9'&&grid[s.y][s.x]>='0'){
        s.m = (grid[s.y][s.x]-'0');
      }
      for(int r = 0; r < 4; r++){
        if(all || s.r == r){
          int nx = (s.x+dx[r]+w)%w;
          int ny = (s.y+dy[r]+h)%h;
          que.push(S(nx,ny,r,s.m));
        }
      }
    }
    cout<<"NO"<<endl;  
END:;
  }
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 0
final_rank: 1

code_snippet: #include<iostream>
#include<vector>
using namespace std;

int r,c,d;
int h,w;
bool table[20][20][16][4];

void move(void){
  if(d == 0){
    w++;
    if(w == c)w = 0;
  }
  else if(d == 2){
    w--;
    if(w < 0)w = c-1;
  }
  else if(d == 3){
    h--;
    if(h < 0)h = r-1;
  }
  else if(d == 1){
    h++;
    if(h == r)h = 0;
  }
}

bool check(int h,int w,int m,int l){
  if(table[h][w][m][l])return false;
  else table[h][w][m][l] = true;
  return true;
}

int main(){
  string tmp;
  vector<string> map;
  int m,pos,flag;
  vector<int> qh,qw,qm,qd;

  m = 0;
  d = 0;
  h = 0;
  w = 0;

  cin >> r >> c;

  for(int i=0;i<r;i++){
    cin >> tmp;
    map.push_back(tmp);
  }

  for(int i=0;i<r;i++){
    for(int j=0;j<c;j++){
      for(int k=0;k<16;k++){
	for(int l=0;l<4;l++)table[i][j][k][l] = false;
      }
    }
  }

  qh.clear();
  qw.clear();
  qm.clear();
  qd.clear();
  pos = 0;

  while(1){
    if(!check(h,w,m,d)){
      if(pos == qh.size()){
	cout << "NO" << endl;
	return 0;
      }else{
	h = qh[pos];
	w = qw[pos];
	m = qm[pos];
	d = qd[pos];
	pos++;
      }
    }

    if(map[h][w] == '@'){
      cout << "YES" << endl;
      return 0;
    }else if(map[h][w] == '>'){
      d = 0;
    }else if(map[h][w] == 'v'){
      d = 1;
    }else if(map[h][w] == '<'){
      d = 2;
    }else if(map[h][w] == '^'){
      d = 3;
    }else if(map[h][w] == '_'){
      if(m)d = 2;
      else d = 0;
    }else if(map[h][w] == '|'){
      if(m)d = 3;
      else d = 1;
    }else if(map[h][w] == '+'){
      m++;
      if(m == 16)m = 0;
    }else if(map[h][w] == '-'){
      m--;
      if(m < 0)m = 15;
    }else if(map[h][w] == '?'){
      flag = 1;
      for(int i=0;i<qh.size();i++){
	if(h == qh[i] && w == qw[i] && m == qm[i]){
	  flag = 0;
	  break;
	}
      }
      if(flag){
	d = 0;
	qh.push_back(h);
	qw.push_back(w);
	qm.push_back(m);
	qd.push_back(1);

	qh.push_back(h);
	qw.push_back(w);
	qm.push_back(m);
	qd.push_back(2);

	qh.push_back(h);
	qw.push_back(w);
	qm.push_back(m);
	qd.push_back(3);
      }
    }else if(map[h][w] == '.'){
    }else{
      m = map[h][w] - '0';
    }

    move();
  }
  
  return 0;
}
accuracy: 1
time_ms: 500
memory_kb: 1412
final_rank: 10

code_snippet: #include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <queue>
#include <set>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
const int INF = 1<<29;

struct P{
  int d;
  int x, y;
  int mem;
  P(int x,int y,int d,int mem):x(x),y(y),d(d),mem(mem) {}
};
bool operator<(const P &a, const P &b) {
  return (a.x!=b.x)? a.x<b.x : a.y!=b.y? a.y<b.y : a.d!=b.d ? a.d < b.d : a.mem < b.mem;
}

int main() {
  int H,W;
  cin >> H >> W;
  char ba[W][H];
  REP(y,H) {
    REP(x,W)
      cin >> ba[x][y];
  }
  int dx[] = {0,1,0,-1};
  int dy[] = {-1,0,1,0};
  queue<P> Q;
  Q.push(P(-1,0,1,0));
  set<P> se;
  bool goal = 0;
  while(!Q.empty()) {
    P now = Q.front();
    Q.pop();
    if (se.count(now)) continue;
    se.insert(now);

//    printf("%d, %d d = %d mem = %d\n", now.x, now.y,now.d, now.mem);
    
    int xx = now.x + dx[now.d];
    int yy = now.y + dy[now.d];
    if (xx<0) xx = W-1;
    else if (xx>=W) xx = 0;
    if (yy<0) yy = H-1;
    else if (yy>=H) yy = 0;
    char c = ba[xx][yy];
    //  cout << c << endl;
    int d = now.d;
    int mem = now.mem;
    if (c == '<') {
      d = 3;
    } else if (c == '>') {
      d = 1;
    } else if (c == '^') {
      d = 0;
    } else if (c == 'v') {
      d = 2;
    } else if (c == '_') {
      if (mem == 0) d = 1;
      else d = 3;
    } else if (c == '|') {
      if (mem == 0) d = 2;
      else d = 0;  
    } else if (c == '?') {
    } else if (c == '.') {
    } else if (c == '@') {
      goal = 1;
      break;
    } else if (isdigit(c)) {
      mem = c-'0';
    } else if (c == '+') {
      if (mem == 15) mem = 0;
      else mem++;
      
    } else if (c == '-') {
      if (mem == 0) mem = 15;
      else mem--;
    }
    if (c == '?') {
      Q.push(P(xx,yy,0,mem));
      Q.push(P(xx,yy,1,mem));
      Q.push(P(xx,yy,2,mem));
      Q.push(P(xx,yy,3,mem));      
    } else {
      Q.push(P(xx,yy,d,mem));
    }
  }
  if (goal) {
    cout << "YES" << endl;
  } else
    cout << "NO" << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 0
final_rank: 1

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
using namespace std;

typedef vector <string> VS;
typedef pair <int, int> PII;
typedef pair <PII, PII> PPP;
typedef set <PPP> SPPP;

int R, C;
VS P;
SPPP M;

bool dfs( int a, int m, int x, int y ) {
  int na = a, nm = m, nx = x, ny = y;
  char op = P[y][x];

  // check
  PPP q( PII( a, m ), PII( x, y ) );
  if ( M.find( q ) != M.end() ) {
    return false;
  }
  M.insert( q );
  
  // operation
  if ( op == '<' ) {
    na = 0;
  } else if ( op == '^' ) {
    na = 1;
  } else if ( op == '>' ) {
    na = 2;
  } else if ( op == 'v' ) {
    na = 3;
  } else if ( op == '_' ) {
    if ( m == 0 ) {
      na = 2;
    } else {
      na = 0;
    }
  } else if ( op == '|' ) {
    if ( m == 0 ) {
      na = 3;
    } else {
      na = 1;
    }
  } else if ( op == '?' ) {
    for ( int i = 0; i < 4; i++ ) {
      na = i;
      int nnx = x, nny = y;
      // move
      if ( na == 0 ) {
	nnx--;
      } else if ( na == 1 ) {
	nny--;
      } else if ( na == 2 ) {
	nnx++;
      } else if ( na == 3 ) {
	nny++;
      }

      if ( nnx >= C ) {
	nnx = 0;
      } else if ( nnx < 0 ) {
	nnx = C - 1;
      }
      if ( nny >= R ) {
	nny = 0;
      } else if ( nny < 0 ) {
	nny = R - 1;
      }

      if ( dfs( na, nm, nnx, nny ) ) return true;
    }
    return false;
  } else if ( op == '.' ) {
    // empty
  } else if ( op == '@' ) {
    return true;
  } else if ( op >= '0' && op <= '9' ) {
    nm = (int)( op - '0' );
  } else if ( op == '+' ) {
    nm = ( nm + 1 ) % 16;
  } else if ( op == '-' ) {
    nm = ( nm - 1 ) % 16;
  }

  // move
  if ( na == 0 ) {
    nx--;
  } else if ( na == 1 ) {
    ny--;
  } else if ( na == 2 ) {
    nx++;
  } else if ( na == 3 ) {
    ny++;
  }

  if ( nx >= C ) {
    nx = 0;
  } else if ( nx < 0 ) {
    nx = C - 1;
  }
  if ( ny >= R ) {
    ny = 0;
  } else if ( ny < 0 ) {
    ny = R - 1;
  }

  if ( dfs( na, nm, nx, ny ) ) return true;
  return false;
}

int main( void ) {
  cin >> R >> C;
  for ( int i = 0; i < R; i++ ) {
    string line;
    cin >> line;
    P.push_back( line );
  }
  bool result = dfs( 2, 0, 0, 0 );
  cout << ( result ? "YES" : "NO" ) << endl;
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 0
final_rank: 1