Problem:
Problem D: Gridgedge
Problem
左上が$(0, 0)$、 右下が$(R-1, C-1)$である$R \times C$マスのグリッドがある。あるマス($e$, $f$)にいるとき、そこから$(e+1, f)$, $(e-1, f)$, $(e, f+1)$, $(e, f-1)$, $(e, 0)$, $(e, C-1)$, $(0, f)$, $(R-1, f)$にはコスト$1$で移動できる。ただしグリッドの外に出ることはできない。マス$(a_i, a_j)$から$(b_i, b_j)$へ移動するとき、最短経路のコストと、最短経路の組み合わせの総数を$10^9 + 7$で割った余りを計算せよ。
ただし、経路の組み合わせは移動の方法によって区別するものとする。たとえば、現在地が$(100, 1)$ のとき、 $(100, 0)$に最短コストで行くには上記$(e, f-1)$か$(e, 0)$で行くことができるので、$2$通りと数える。
Input
入力は以下の形式で与えられる。
$R$ $C$ $a_i$ $a_j$ $b_i$ $b_j$
Constraints
入力は以下の条件を満たす。
$1 \le R, C \le 500$
$0 \le a_i, b_i \le R - 1$
$0 \le a_j, b_j \le C - 1$
与えられる入力は全て整数である。
Output
マス$(a_i, a_j)$から$(b_i, b_j)$へ移動するとき、最短経路のコストと、最短経路の組み合わせの総数を$10^9+7$で割った余りを空白区切りで$1$行に出力せよ。
Sample Input 1
2 2 0 0 1 1
Sample Output 1
2 8
Sample Input 2
1 1 0 0 0 0
Sample Output 2
0 1
Sample Input 3
1 10 0 0 0 9
Sample Output 3
1 1
Sample Input 4
5 5 0 0 4 4
Sample Output 4
2 2
Sample Input 5
421 435 196 169 388 9
Sample Output 5
43 917334776

Submitted solutions:

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

using namespace std;

const int N = 501;
const int P = N * N;
const int INF = 1e9 + 128;
const int MOD = 1e9 + 7;

int d[P], cnt[P];
vector<int> g[P];

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

int r, c;

int get(int x, int y) {
    return x * c + y;
}

bool ok(int x, int y) {
    return 0 <= x && x < r && 0 <= y && y < c;
}

int main() {
    cin >> r >> c;

    for (int i = 0; i < r; i++)
        for (int j = 0; j < c; j++) {
            int cnode = get(i, j);
            d[cnode] = INF;
            for (int x = 0; x < 4; x++) {
                int ni = i + dx[x], nj = j + dy[x];
                if (ok(ni, nj))
                    g[cnode].push_back(get(ni, nj));
            }
            for (int x : {0, r - 1})
                g[cnode].push_back(get(x, j));
            for (int y : {0, c - 1})
                g[cnode].push_back(get(i, y));
        }

    int a, b;
    cin >> a >> b;
    int snode = get(a, b);

    cin >> a >> b;
    int dnode = get(a, b);

    d[snode] = 0;
    cnt[snode] = 1;

    queue <int> q;
    q.push(snode);

    while (!q.empty()) {
        int node = q.front(); q.pop();

        for (int i = 0; i < (int)g[node].size(); ) {
            int j = i;
            while (j < (int)g[node].size() && g[node][i] == g[node][j])
                ++j;
            int to = g[node][i];
            int cc = j - i;
            if (d[to] > d[node] + 1)
                d[to] = d[node] + 1, cnt[to] = (cc * cnt[node]) % MOD, q.push(to);
            else if (d[to] == d[node] + 1)
                cnt[to] = (cnt[to] + cc * cnt[node]) % MOD;
            i = j;
        }
    }

    cout << d[dnode] << ' ' << cnt[dnode] << '\n';

    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 19344
final_rank: 12

code_snippet: #include <iostream>
#include <algorithm>
#include <string.h>
#include <stdio.h>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
#include <set>
using namespace std;
typedef long long ll;
int mov[4][2]={{1,0},{0,1},{0,-1},{-1,0}};
int dis[505][505];
ll ans[505][505];
int vis[505][505];
const int inf=1000000007;
int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int r,c,a,b,xxx,yyy;
    cin>>r>>c>>a>>b>>xxx>>yyy;
    for(int i=0;i<r;i++){
        for(int j=0;j<c;j++)
            dis[i][j]=1000;
    }
    dis[a][b]=0;
    queue<pair<int,int> >  q;
    q.push(make_pair(a,b));
    while(!q.empty()){
        int x=q.front().first,y=q.front().second;
        q.pop();
        for(int i=0;i<4;i++){
            int xx=x+mov[i][0],yy=y+mov[i][1];
            if(xx>=0&&yy>=0&&xx<r&&yy<c){
                if(dis[xx][yy]>dis[x][y]+1){
                    dis[xx][yy]=dis[x][y]+1;
                    q.push(make_pair(xx,yy));
                }
            }
        }
        int xx=x,yy=y;
        xx=0;
        if(dis[xx][yy]>dis[x][y]+1){
            dis[xx][yy]=dis[x][y]+1;
            q.push(make_pair(xx,yy));
        }
        xx=r-1;
        if(dis[xx][yy]>dis[x][y]+1){
            dis[xx][yy]=dis[x][y]+1;
            q.push(make_pair(xx,yy));
        }
        xx=x,yy=0;
        if(dis[xx][yy]>dis[x][y]+1){
            dis[xx][yy]=dis[x][y]+1;
            q.push(make_pair(xx,yy));
        }
        yy=c-1;
        if(dis[xx][yy]>dis[x][y]+1){
            dis[xx][yy]=dis[x][y]+1;
            q.push(make_pair(xx,yy));
        }
    }
    cout<<dis[xxx][yyy]<<" ";
    vis[a][b]=1;
    ans[a][b]=1;
    while(!q.empty()) q.pop();
    q.push(make_pair(a,b));
    while(!q.empty()){
        int x=q.front().first,y=q.front().second;
        q.pop();
        int xx,yy;
        for(int i=0;i<4;i++){
            xx=x+mov[i][0],yy=y+mov[i][1];
            if(xx>=0&&yy>=0&&xx<r&&y<c){
                if(dis[xx][yy]>dis[x][y]){
                    ans[xx][yy]=(ans[xx][yy]+ans[x][y])%inf;
                }
                if(!vis[xx][yy]){
                    vis[xx][yy]=1;
                    q.push(make_pair(xx,yy));
                }
            }
        }
        xx=0,yy=y;
        if(dis[xx][yy]>dis[x][y]){
            ans[xx][yy]=(ans[xx][yy]+ans[x][y])%inf;
        }
        if(!vis[xx][yy]){
            vis[xx][yy]=1;
            q.push(make_pair(xx,yy));
        }
        xx=r-1;
        if(dis[xx][yy]>dis[x][y]){
            ans[xx][yy]=(ans[xx][yy]+ans[x][y])%inf;
        }
        if(!vis[xx][yy]){
            vis[xx][yy]=1;
            q.push(make_pair(xx,yy));
        }
        xx=x,yy=0;
        if(dis[xx][yy]>dis[x][y]){
            ans[xx][yy]=(ans[xx][yy]+ans[x][y])%inf;
        }
        if(!vis[xx][yy]){
            vis[xx][yy]=1;
            q.push(make_pair(xx,yy));
        }
        yy=c-1;
        if(dis[xx][yy]>dis[x][y]){
            ans[xx][yy]=(ans[xx][yy]+ans[x][y])%inf;
        }
        if(!vis[xx][yy]){
            vis[xx][yy]=1;
            q.push(make_pair(xx,yy));
        }
    }
    cout<<ans[xxx][yyy]<<endl;
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 6948
final_rank: 3

code_snippet: #include <iostream>
#include <algorithm>
#include <string.h>
#include <stdio.h>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
#include <set>
using namespace std;
typedef long long ll;
int mov[4][2]={{1,0},{0,1},{0,-1},{-1,0}};
int dis[505][505];
ll ans[505][505];
int vis[505][505];
int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int r,c,a,b,xxx,yyy;
    cin>>r>>c>>a>>b>>xxx>>yyy;
    for(int i=0;i<r;i++){
        for(int j=0;j<c;j++)
            dis[i][j]=1000;
    }
    dis[a][b]=0;
    queue<pair<int,int> >  q;
    q.push(make_pair(a,b));
    while(!q.empty()){
        int x=q.front().first,y=q.front().second;
        q.pop();
        for(int i=0;i<4;i++){
            int xx=x+mov[i][0],yy=y+mov[i][1];
            if(xx>=0&&yy>=0&&xx<r&&yy<c){
                if(dis[xx][yy]>dis[x][y]+1){
                    dis[xx][yy]=dis[x][y]+1;
                    q.push(make_pair(xx,yy));
                }
            }
        }
        int xx=x,yy=y;
        xx=0;
        if(dis[xx][yy]>dis[x][y]+1){
            dis[xx][yy]=dis[x][y]+1;
            q.push(make_pair(xx,yy));
        }
        xx=r-1;
        if(dis[xx][yy]>dis[x][y]+1){
            dis[xx][yy]=dis[x][y]+1;
            q.push(make_pair(xx,yy));
        }
        xx=x,yy=0;
        if(dis[xx][yy]>dis[x][y]+1){
            dis[xx][yy]=dis[x][y]+1;
            q.push(make_pair(xx,yy));
        }
        yy=c-1;
        if(dis[xx][yy]>dis[x][y]+1){
            dis[xx][yy]=dis[x][y]+1;
            q.push(make_pair(xx,yy));
        }
    }
    cout<<dis[xxx][yyy]<<" ";
    vis[a][b]=1;
    ans[a][b]=1;
    while(!q.empty()) q.pop();
    q.push(make_pair(a,b));
    while(!q.empty()){
        int x=q.front().first,y=q.front().second;
        q.pop();
        int xx,yy;
        for(int i=0;i<4;i++){
            xx=x+mov[i][0],yy=y+mov[i][1];
            if(xx>=0&&yy>=0&&xx<r&&y<c){
                if(dis[xx][yy]>dis[x][y]){
                    ans[xx][yy]+=ans[x][y];
                }
                if(!vis[xx][yy]){
                    vis[xx][yy]=1;
                    q.push(make_pair(xx,yy));
                }
            }
        }
        xx=0,yy=y;
        if(dis[xx][yy]>dis[x][y]){
            ans[xx][yy]+=ans[x][y];
        }
        if(!vis[xx][yy]){
            vis[xx][yy]=1;
            q.push(make_pair(xx,yy));
        }
        xx=r-1;
        if(dis[xx][yy]>dis[x][y]){
            ans[xx][yy]+=ans[x][y];
        }
        if(!vis[xx][yy]){
            vis[xx][yy]=1;
            q.push(make_pair(xx,yy));
        }
        xx=x,yy=0;
        if(dis[xx][yy]>dis[x][y]){
            ans[xx][yy]+=ans[x][y];
        }
        if(!vis[xx][yy]){
            vis[xx][yy]=1;
            q.push(make_pair(xx,yy));
        }
        yy=c-1;
        if(dis[xx][yy]>dis[x][y]){
            ans[xx][yy]+=ans[x][y];
        }
        if(!vis[xx][yy]){
            vis[xx][yy]=1;
            q.push(make_pair(xx,yy));
        }
    }
    cout<<ans[xxx][yyy]%1000000007<<endl;
    return 0;
}
accuracy: 0.2982456140350877
time_ms: 10
memory_kb: 6904
final_rank: 20

code_snippet: #include <bits/stdc++.h>
#include <algorithm>
#include <cmath>
#include <set>
#include <cstdio>
#include <vector>
#include <iostream>
#include <utility>
#include <queue>
#include <map>
#include <complex>
#define fir first
#define sec second
#define sz(s) (s).size()
#define pb push_back
#define get(n) scanf("%d",&n);
#define gets(s) string s;cin >> (s);
#define prfi(n) printf("%d", &n);
#define prfd(n) printf("%lf", &n);
#define All(s) (s).begin(), (s).end()
#define rep(i,j) for(int (i)=0;(i)<(j);(i)++)
#define For(i,j,k) for(int (i)=(j);(i)<(k);(i)++)
#define drep(i,j) for(int (i)=(j);(i)>=0;(i)--)
#define Ford(i,j,k) for(int (i)=(j);i>=(k);i--)
#define fore(c,v) for(auto (c): (v))
#define lp for(int __=0;__<n;i++)
#define mem(a,b) memset(a,b,sizeof(a));
#define dump(x)  std::cout << #x << " = " << (x) << std::endl;
#define debug(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;
using ull = unsigned long long int;
using ll = long long;
using ld = long double;
using pii = std::pair<int,int>;
using pll = std::pair<ll, ll>;
using vi = std::vector<int> ;
using vvi = std::vector<vi> ;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vd = std::vector<double> ;
using vvd = std::vector<vd> ;
using qi = std::queue<int> ;
using vpii = std::vector<std::pair<int, int> >;
using vpll = std::vector<pll>;
using namespace std;

const int Mod = (1e9) + 7;
const int INF = 1e9 + 19;
const ll INFL = 1e18 + 19;
const int dx[] = {-1, 0, 0, 1};
const int dy[] = {0, -1, 1, 0};
const int dx2[] = {-1, -1, -1, 0, 0, 0, 1, 1, 1};
const int dy2[] = {1, 0, -1, 1, 0, -1, 1, 0, -1};
const double EPS = 1e-10;
//_____________________________________Templates_________________________________________//

template<class T1, class T2> inline void chmin(T1 &a, T2 b){if(a > b) a = b;}
template<class T1, class T2> inline void chmax(T1 &a, T2 b){if(a < b) a = b;}
template<class T> inline void pri(T a){cout << a << endl;}
template<class Z> using vec = vector<Z>;
template<class T> using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
//mainly use for dynamic prog
template<class T1, class T2>
void update(T1 &a, T2 b){
  a += b;
  if(a > Mod) a %= Mod;
}

inline void IN(void){
  return;
}

template <typename First, typename... Rest>
void IN(First& first, Rest&... rest){
  cin >> first;
  IN(rest...);
  return;
}

inline void OUT(void){
  cout << "\n";
  return;
}

template <typename First, typename... Rest>
void OUT(First first, Rest... rest){
  cout << first << " ";
  OUT(rest...);
  return;
}

bool pairsort(pll pl, pll pr){
  if(pl.first == pr.first)return pl.second > pr.second;
  return pl.first < pr.first;
}

int cntbit(ll a,int n,int j){int res = 0;For(i,j,n){if(a>>i & 1){res++;}}return res;}
vector<int> make_bit(int a){vector<int> res; for(int i=31;i>=0;i--)if(a&(1<<i))res.pb(i);return res;}
bool stdbit(int a, int b){return a&(1 << b); }
int GCD(int a, int b){if(b > a)return GCD(b,a);if(a%b == 0)return b;else return GCD(b, a%b);}
int LCM(int a, int b){return a*b/GCD(a,b);}
int roundup(int a, int b){if(a % b == 0)return a/b;else return (a+b)/b;}
int rounddown(int a, int b){if(a%b == 0)return a/b;else {return (a-b)/b;}}
ll pow(ll a, ll n){ll res = 1;while(n > 0){if(n&1)res *= a; a *= a; n = n >> 1;}return res;}
ll GetDiviserCount(ll N)//約数の個数
{
  ll res = 1;
  For(i,2,sqrt(N)+1)
  {
    ll cnt = 0;
    while(N%i == 0)
    {
      cnt++;
      N /= i;
    }
    res *= (cnt + 1);
    if(N == 1)break;
  }
  if(N != 1)res *= 2;
  return res;
}
vll GetDivisor(ll N)//約数列挙
{
  vll res;
  for(ll i = 1;i*i <= N;i++)
  {
    if(N%i == 0)
    {
      res.pb(i);
      if(i*i != N)res.pb(N/i);
    }
  }
  sort(All(res));
  return res;
}


struct mint {
  ll x; // typedef long long ll;
  mint(ll x=0):x((x%Mod+Mod)%Mod){}
  mint operator-() const { return mint(-x);}
  mint& operator+=(const mint a) {
    if ((x += a.x) >= Mod) x -= Mod;
    return *this;
  }
  mint& operator-=(const mint a) {
    if ((x += Mod-a.x) >= Mod) x -= Mod;
    return *this;
  }
  mint& operator*=(const mint a) {
    (x *= a.x) %= Mod;
    return *this;
  }
  mint operator+(const mint a) const {
    mint res(*this);
    return res+=a;
  }
  mint operator-(const mint a) const {
    mint res(*this);
    return res-=a;
  }
  mint operator*(const mint a) const {
    mint res(*this);
    return res*=a;
  }
  mint pow(ll t) const {
    if (!t) return 1;
    mint a = pow(t>>1);
    a *= a;
    if (t&1) a *= *this;
    return a;
  }
 
  // for prime mod
  mint inv() const {
    return pow(Mod-2);
  }
  mint& operator/=(const mint a) {
    return (*this) *= a.inv();
  }
  mint operator/(const mint a) const {
    mint res(*this);
    return res/=a;
  }
  friend ostream& operator<<(ostream& os, const mint& a);
};
ostream& operator<<(ostream& os, const mint& a)
{
  os << a.x;
  return os;
}
struct combination {
  vector<mint> fact, ifact;
  combination(int n):fact(n+1),ifact(n+1) {
    assert(n < Mod);
    fact[0] = 1;
    for (int i = 1; i <= n; ++i) fact[i] = fact[i-1]*i;
    ifact[n] = fact[n].inv();
    for (int i = n; i >= 1; --i) ifact[i-1] = ifact[i]*i;
  }
  mint operator()(int n, int k) {
    if (k < 0 || k > n) return 0;
    return fact[n]*ifact[k]*ifact[n-k];
  }
};
 
template<class Z>
struct MyMatrix
{
  using mat = MyMatrix<Z>;
  vector<vector<Z>> m_dat;
  int m_h;
  int m_w;
  MyMatrix(int h, int w) : m_h(h), m_w(w) ,m_dat(h,vector<Z>(w)) {}
  vector<Z> &operator[] (int idx)
  {
    return m_dat[idx];
  }
  mat Multiple(mat &a)
  {
    mat C(m_h, a.m_w);
    for(int i=0;i<m_h;i++)
    {
      for(int j=0;j<a.m_w;j++)
      {
        for(int k=0;k<m_w;k++)
        {
         C[i][j] += m_dat[i][k] * a[k][j];
        }
      }
    }
    return C;
  }
  mat Pow(ll x)
  {
    mat B(m_h,m_w);
    for(int i=0;i<m_h;i++)
    {
      B[i][i] = 1;
    }
    mat A = *this;
    while(x > 0)
    {
      if(x&1)B = B.Multiple(A);
      A = A.Multiple(A);
      x = x >> 1;
    }
    return B;
  }
  //friend ostream& operator<<(ostream &os, const mat &A);
};
/*
template<class Z>
ostream& operator<<(ostream &os, Matrix<Z>& A)
{
  for(int i=0;i<A.m_h;i++)
  {
    for(int j=0;j<A.m_w;j++)
    {
      os << A[i][j] << " ";
    }
    os << endl;
  }
  return os;
}
*/
template<class T>
using mat = MyMatrix<T>;
//_____________________　following sorce code_________________________//
const int max_n = 3 * (1e5) + 1;
const int max_m = 83 * (1e5) + 1;

int n,m,k;
ll N;
int h,w;
string S;
//int a,b,c;
vi v;
int ans;
double x,y,z;
int a[2],b[2];
vector<int> G[1010101];
struct Data
{ 
  int cost;
  int x,y;
  Data(int cost,int x,int y) : cost(cost),x(x),y(y) {}
  bool operator>(const Data &a) const
  {
    return cost > a.cost;
  }
};
mint times[1000][1000];
int cost[1000][10000];
int visit[1010][1010];
void Dijkstra()
{
  min_priority_queue<Data> qu;
  memset(times,0,sizeof(times));
  memset(cost,INF,sizeof(cost));
  memset(visit,false,sizeof(visit));
  qu.push(Data(0,a[0],b[0]));
  times[a[0]][b[0]] = 1;
  cost[a[0]][b[0]] = 0;
  while(qu.size())
  {
    auto e = qu.top(); qu.pop();
    if(visit[e.x][e.y])continue;
    visit[e.x][e.y] = true;
    rep(i,4)
    {
      int nx = e.x + dx[i];
      int ny = e.y + dy[i];
      if(nx >= 0 and nx < h and ny >= 0 and ny < w)
      {
        if(cost[nx][ny] == e.cost + 1)
        {
          times[nx][ny] += times[e.x][e.y];
          qu.push(Data(e.cost+1,nx,ny));
        }
        if(cost[nx][ny] > e.cost + 1)
        {
          times[nx][ny] = times[e.x][e.y];
          cost[nx][ny] = e.cost + 1;
          qu.push(Data(e.cost+1,nx,ny));
        }
      }
    }

    if(e.x != 0)
    {
      if(cost[0][e.y] == e.cost + 1)
      {
        times[0][e.y] += times[e.x][e.y];
        qu.push(Data(e.cost+1,0,e.y));
      }
      else if(cost[0][e.y] > e.cost + 1)
      {
        times[0][e.y] = times[e.x][e.y];
        cost[0][e.y] = e.cost + 1;
        qu.push(Data(e.cost+1,0,e.y));
      }
    }
    if(e.x != h-1)
    {
      if(cost[h-1][e.y] == e.cost + 1)
      {
        times[h-1][e.y] += times[e.x][e.y];
        qu.push(Data(e.cost+1,h-1,e.y));
      }
      else if(cost[h-1][e.y] > e.cost + 1)
      {
        times[h-1][e.y] = times[e.x][e.y];
        cost[h-1][e.y] = e.cost + 1;
        qu.push(Data(e.cost+1,h-1,e.y));
      }
    }
    if(e.y != 0)
    {
      if(cost[e.x][0] == e.cost + 1)
      {
        times[e.x][0] += times[e.x][e.y];
        qu.push(Data(e.cost+1,e.x,0));
      }
      else if(cost[e.x][0] > e.cost + 1)
      {
        times[e.x][0] = times[e.x][e.y];
        cost[e.x][0] = e.cost + 1;
        qu.push(Data(e.cost+1,e.x,0));
      }
    }
    if(e.y != w-1)
    {
      if(cost[e.x][w-1] == e.cost + 1)
      {
        times[e.x][w-1] += times[e.x][e.y];
        qu.push(Data(e.cost+1,e.x,w-1));
      }
      else if(cost[e.x][w-1] > e.cost + 1)
      {
        times[e.x][w-1] = times[e.x][e.y];
        cost[e.x][w-1] = e.cost + 1;
        qu.push(Data(e.cost+1,e.x,w-1));
      }
    }
  }
}

signed main (int argc, char* argv[]) {
  cin.tie(0);
  ios::sync_with_stdio(false);
  IN(h,w,a[0],b[0],a[1],b[1]);
  Dijkstra();
  cout << cost[a[1]][b[1]] << " " << times[a[1]][b[1]] << endl;
  //dump(times[1][1]);
  //for(auto c : ans){cout << c << endl;}
  //cout << fixed << setprecision(15) << ans << endl;
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 77820
final_rank: 15

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int MOD = (int)1e9 + 7;

template<class T> using Rig = pair<T, long long>;
template<class T> Rig<T> add(const Rig<T> &a, const Rig<T> &b) {
    if (a.first != b.first) return min(a, b);
    return Rig<T>(a.first, (a.second + b.second) % MOD);
}
template<class T> Rig<T> mul(const Rig<T> &a, const Rig<T> &b) {
    return Rig<T>(a.first + b.first, a.second * b.second % MOD);
}

template<class T, class S> ostream& operator<<(ostream& os, const pair<T, S>& p) { return os << p.first << " " << p.second; }
const int INF = (int)1e9 + 7;
using pii = pair<int, int>;
int main() {
    int h, w; cin >> h >> w;
    int si, sj, ti, tj; cin >> si >> sj >> ti >> tj;
    vector<vector<Rig<int>>> dp(h, vector<Rig<int>>(w, Rig<int>(INF, 0)));
    vector<vector<bool>> done(h, vector<bool>(w));
    queue<pair<Rig<int>, pii>> que;
    dp[si][sj] = Rig<int>(0, 1);
    que.emplace(dp[si][sj], pii(si, sj));
    while (!que.empty()) {
        pii p = que.front().second; que.pop();
        int i = p.first, j = p.second;
        if (done[i][j]) continue;
        done[i][j] = true;
        int dij[] = {0, 1, 0, -1, 0};
        for (int k = 0; k < 4; k++) {
            int ni = i + dij[k], nj = j + dij[k + 1];
            if (ni < 0 || ni >= h || nj < 0 || nj >= w) continue;
            dp[ni][nj] = add(dp[ni][nj], mul(dp[i][j], Rig<int>(1, 1)));
            que.emplace(dp[ni][nj], pii(ni, nj));
        }
        int nis[] = {i, i, 0, h - 1}, njs[] = {0, w - 1, j, j};
        for (int k = 0; k < 4; k++) {
            int ni = nis[k], nj = njs[k];
            dp[ni][nj] = add(dp[ni][nj], mul(dp[i][j], Rig<int>(1, 1)));
            que.emplace(dp[ni][nj], pii(ni, nj));
        }
    }
    cout << dp[ti][tj] << endl;
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 6152
final_rank: 8

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int MOD = (int)1e9 + 7;

template<class T> using Rig = pair<T, long long>;
template<class T> Rig<T> add(const Rig<T> &a, const Rig<T> &b) {
    if (a.first != b.first) return min(a, b);
    return Rig<T>(a.first, (a.second + b.second) % MOD);
}
template<class T> Rig<T> mul(const Rig<T> &a, const Rig<T> &b) {
    return Rig<T>(a.first + b.first, a.second * b.second % MOD);
}

using pii = pair<int, int>;
const int INF = (int)1e9 + 7;
template<class T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template<class T, class S> ostream& operator<<(ostream& os, const pair<T, S>& p) { return os << p.first << " " << p.second; }
int main() {
    int h, w; cin >> h >> w;
    int si, sj, ti, tj; cin >> si >> sj >> ti >> tj;
    vector<vector<Rig<int>>> dp(h, vector<Rig<int>>(w, Rig<int>(INF, 0)));
    vector<vector<bool>> done(h, vector<bool>(w));
    min_heap<pair<Rig<int>, pii>> pq;
    pq.emplace(dp[si][sj] = Rig<int>(0, 1), pii(si, sj));
    while (!pq.empty()) {
        pii p = pq.top().second; pq.pop();
        int i = p.first, j = p.second;
        if (done[i][j]) continue;
        done[i][j] = true;
        int dij[] = {0, 1, 0, -1, 0};
        for (int k = 0; k < 4; k++) {
            int ni = i + dij[k], nj = j + dij[k + 1];
            if (ni < 0 || ni >= h || nj < 0 || nj >= w) continue;
            dp[ni][nj] = add(dp[ni][nj], mul(dp[i][j], Rig<int>(1, 1)));
            pq.emplace(dp[ni][nj], pii(ni, nj));
        }
        int nis[] = {i, i, 0, h - 1}, njs[] = {0, w - 1, j, j};
        for (int k = 0; k < 4; k++) {
            int ni = nis[k], nj = njs[k];
            dp[ni][nj] = add(dp[ni][nj], mul(dp[i][j], Rig<int>(1, 1)));
            pq.emplace(dp[ni][nj], pii(ni, nj));
        }
    }
    cout << dp[ti][tj] << endl;
    return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 6096
final_rank: 18

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
using pii = pair<int, int>;
const int INF = (int)1e9 + 7;
const int MOD = (int)1e9 + 7;
template<class T> void add(T &a, T b) { (a += (b % MOD + MOD) % MOD) %= MOD; }
template<class T> inline bool chmin(T &a, T b) { return a > b ? (a = b, 1) : 0; }

int main() {
    int h, w; cin >> h >> w;
    int si, sj, ti, tj; cin >> si >> sj >> ti >> tj;
    vector<vector<int>> dist(h, vector<int>(w, INF));
    vector<vector<int>> dp(h + 1, vector<int>(w + 1));
    vector<pair<pii, pii>> cur;
    cur.emplace_back(pii(si, sj), pii(h, w)), dp[h][w] = 1;
    for (int k = 0; !cur.empty(); k++) {
        vector<pair<pii, pii>> nxt;
        for (auto &p: cur) {
            int i = p.first.first, j = p.first.second;
            int prv = dp[p.second.first][p.second.second];
            if (chmin(dist[i][j], k)) {
                dp[i][j] = prv;
                int dij[] = {0, 1, 0, -1, 0};
                for (int d = 0; d < 4; d++) {
                    int ni = i + dij[d], nj = j + dij[d + 1];
                    if (ni < 0 || ni >= h || nj < 0 || nj >= w) continue;
                    nxt.emplace_back(pii(ni, nj), pii(i, j));
                } {
                    nxt.emplace_back(pii(i, 0), pii(i, j));
                    nxt.emplace_back(pii(i, w - 1), pii(i, j));
                    nxt.emplace_back(pii(0, j), pii(i, j));
                    nxt.emplace_back(pii(h - 1, j), pii(i, j));
                }
            } else if (dist[i][j] == k) {
                add(dp[i][j], prv);
            }
        }
        cur = nxt;
    }
    cout << dist[ti][tj] << " " << dp[ti][tj] << endl;
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 5212
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define INF 329496729612
#define int long long
#define MOD (int)(1e9+7)
#define MAX 500
typedef  pair<int,int> P;

int r, c, ax, ay, by, bx, ans, temp;
int grid[MAX+10][MAX+10],countg[MAX+10][MAX+10], flags[MAX+10][MAX+10], dxy[4] = {1, -1, 0, 0};

void huga(){
  queue<P> Q;
  Q.push(P(ax,ay));

  for(int i = 0; i <= MAX; i++)
    for(int j = 0; j <= MAX; j++)
      grid[i][j] = INF;

  grid[ay][ax] = 0;
  countg[ay][ax]=1;

  while(!Q.empty()){
    P p = Q.front();Q.pop();
    int x = p.first, y=p.second,ny, nx;
    // int  rc[2][4] = {{x,x,0,r-1},{0,c-1,y,y}};
    int  rc[2][4] = {{x,x,0,c-1},{0,r-1,y,y}};
    for(int i = 0; i < 8; i++){
      if(i < 4) nx = x + dxy[i], ny = y + dxy[3-i];
      else  ny = rc[1][i-4], nx = rc[0][i-4];

      if(0 <= nx && nx < c && 0 <= ny && ny < r){
	if(grid[y][x]+1 < grid[ny][nx]){
	  grid[ny][nx] = grid[y][x]+1;
	  if(nx != bx|| ny != by)Q.push(P(nx,ny));
	}
      }
    }
  }

  Q.push(P(ax,ay));
  while(!Q.empty()){
    P p = Q.front();Q.pop();
    int x = p.first, y=p.second,ny, nx;
    // int  rc[2][4] = {{x,x,0,r-1},{0,c-1,y,y}};
    int  rc[2][4] = {{x,x,0,c-1},{0,r-1,y,y}};
    if(flags[y][x])continue;
    else flags[y][x]=1;
    for(int i = 0; i < 8; i++){
      if(i < 4) nx = x + dxy[i], ny = y + dxy[3-i];
      else  ny = rc[1][i-4], nx = rc[0][i-4];

      if(0 <= nx && nx < c && 0 <= ny && ny < r){
	if(grid[y][x]+1 == grid[ny][nx]){
	  countg[ny][nx] += countg[y][x];
	  if(nx != bx|| ny != by)Q.push(P(nx,ny));
	  countg[ny][nx] %= MOD;
	}
      }
    }
  }
}

signed main(){
  cin>>r>>c>>ay>>ax>>by>>bx;

  huga();

  cout<<grid[by][bx]<<" "<<countg[by][bx]%MOD<<endl;

  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 8948
final_rank: 4

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

using namespace std;

typedef long long ll;
typedef pair<ll,ll> P;

#define _upgrade ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define rep(i,x) for(ll i = 0; i < (ll)(x); i++)
#define all(x) (x).begin(), (x).end()
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define pb push_back

template<class T1, class T2> void chmin(T1 &a, T2 b){if(a>b)a=b;}
template<class T1, class T2> void chmax(T1 &a, T2 b){if(a<b)a=b;}
template<typename T> using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;

//ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}
//ll lcm(ll x, ll y) {return x / gcd(x, y) * y;}

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

const ll INF = 1e9;
const long double PI = 3.14159265358979323846;


// ****************************************CODE***************************************//

template<int MOD> struct ModInt {
    static const int Mod = MOD; unsigned x; ModInt() : x(0) { }
    ModInt(signed sig) { x = sig < 0 ? sig % MOD + MOD : sig % MOD; }
    ModInt(signed long long sig) { x = sig < 0 ? sig % MOD + MOD : sig % MOD; }
    int get() const { return (int)x; }
    ModInt &operator+=(ModInt that) { if ((x += that.x) >= MOD) x -= MOD; return *this; }
    ModInt &operator-=(ModInt that) { if ((x += MOD - that.x) >= MOD) x -= MOD; return *this; }
    ModInt &operator*=(ModInt that) { x = (unsigned long long)x * that.x % MOD; return *this; }
    ModInt &operator/=(ModInt that) { return *this *= that.inverse(); }
    ModInt operator+(ModInt that) const { return ModInt(*this) += that; }
    ModInt operator-(ModInt that) const { return ModInt(*this) -= that; }
    ModInt operator*(ModInt that) const { return ModInt(*this) *= that; }
    ModInt operator/(ModInt that) const { return ModInt(*this) /= that; }
    ModInt inverse() const {
        long long a = x, b = MOD, u = 1, v = 0;
        while (b) { long long t = a / b; a -= t * b; std::swap(a, b); u -= t * v; std::swap(u, v); }
        return ModInt(u);
    }
    bool operator==(ModInt that) const { return x == that.x; }
    bool operator!=(ModInt that) const { return x != that.x; }
    ModInt operator-() const { ModInt t; t.x = x == 0 ? 0 : Mod - x; return t; }
};
template<int MOD> ostream& operator<<(ostream& st, const ModInt<MOD> a) { st << a.get(); return st; };
template<int MOD> ModInt<MOD> operator^(ModInt<MOD> a, unsigned long long k) {
    ModInt<MOD> r = 1; while (k) { if (k & 1) r *= a; a *= a; k >>= 1; } return r;
}
typedef ModInt<1000000007> mint;



int W, H, ax, ay, bx, by;
int dst[505][505], vis[505][505];
mint cnt[505][505];

int main(){
    cin >> W >> H >> ax >> ay >> bx >> by;

    rep(y,H) rep(x,W) dst[y][x] = INF;
    min_priority_queue<pair<int, int>> que;

    dst[ay][ax] = 0;
    cnt[ay][ax] = 1;
    que.push({0, ay * 1010 + ax});
    while(!que.empty()){
        auto q = que.top(); que.pop();

        //この場合分けのやり方すごい画期的過ぎんか
        //何それすごいってやつ
        //んーコストとグリッド状の座標を保存する時にこれは便利になるのかなーと思う。すごいなー。
        //今回はグラフを作るという作業はしないみたいやね。というよりはもともと全てのグラフはグリッドとして用意されていてあとはコストが1ってある程度決まってるからbfs的な感じでも解けるんだよね。
        //
        int x = q.second % 1010;
        int y = q.second / 1010;
        int c = q.first;

        if(vis[y][x]) continue;
        vis[y][x] = 1;

        if(y == by and x == bx){
            cout << c << " " << cnt[y][x] << endl;
            return 0;
        }

        //次に行くパターンを全部ここに入れるのかーなるほど
        vector<pair<int, int>> nxt;
        rep(i,4) nxt.push_back({x + dx[i], y + dy[i]});
        nxt.push_back({0,y});
        nxt.push_back({W-1, y});
        nxt.push_back({x, 0});
        nxt.push_back({x, H-1});

        for(auto p : nxt){
            int xx, yy;
            tie(xx, yy) = p;

            if(xx < 0 or W <= xx or yy < 0 or H <= yy) continue;

            //最短経路数問題の感じはこんな感じだねー覚えとかないとねー
            if(c + 1 < dst[yy][xx]){
                dst[yy][xx] = c + 1;
                cnt[yy][xx] = cnt[y][x];
                que.push({c + 1, yy * 1010 + xx});
            }
            else if(c+1 == dst[yy][xx]) cnt[yy][xx] += cnt[y][x];
        }
    }

}
accuracy: 1
time_ms: 10
memory_kb: 5308
final_rank: 1

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

using namespace std;

typedef long long ll;
typedef long double Double;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)


namespace sub {
    template<typename T>
    constexpr typename std::enable_if<std::is_integral<T>::value, T>::type
    inf_sub() {
        return std::numeric_limits<T>::max() / 2 - 1000;
    }

    template<typename T>
    constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
    inf_sub() {
        return std::min(std::numeric_limits<T>::max() / 2 - 1000, T(1e50));
    }
}  // namespace sub

template<typename T>
constexpr T inf() {
    static_assert(std::is_arithmetic<T>::value, "T must be arithmetic value");
    return sub::inf_sub<T>();
}

template<typename T>
constexpr T zero() {
    static_assert(std::is_arithmetic<T>::value, "T must be arithmetic value");
    return T(0);
}

const long double pi = acos(-1.0);

template<class edge_t>
class graph_t {
    std::vector<std::vector<edge_t>> g;

public:
    using reference = std::vector<edge_t> &;
    using const_reference = const std::vector<edge_t> &;
    using iterator = typename std::vector<edge_t>::iterator;

    graph_t() : g(0) { ; }

    graph_t(int n) : g(n) { ; }

    int size() const { return g.size(); }

    void push_back(const std::vector<edge_t> &es) { g.push_back(es); }

    reference operator[](int x) { return g[x]; }

    const_reference operator[](int x) const { return g[x]; }

    iterator &begin() { return begin(g); }

    iterator &end() { return end(g); }
};

template<typename edge_t, typename cost_type = typename edge_t::cost_type>
std::vector<cost_type> dijkstra(const graph_t<edge_t> &g, int s) {
    std::vector<cost_type> d(g.size(), inf<cost_type>());
    d[s] = zero<cost_type>();
    using P = std::pair<cost_type, int>;
    std::priority_queue<P, std::vector<P>, std::greater<P>> que;
    que.push(P(zero<cost_type>(), s));
    while (!que.empty()) {
        cost_type dist = que.top().first;
        int v = que.top().second;
        que.pop();
        if (d[v] < dist) continue;
        for (const auto &e : g[v]) {
            if (d[e.to] <= d[v] + e.cost) continue;
            d[e.to] = d[v] + e.cost;
            que.push(P(d[e.to], e.to));
        }
    }
    return d;
}


template<typename Cost>
class WeightedEdge {
public:
    using cost_type = Cost;
    int to;
    cost_type cost;

    WeightedEdge(int, int t, cost_type c) : to(t), cost(c) { ; }
};

template<typename Cost> using WeightedGraph = graph_t<WeightedEdge<Cost>>;

template<typename Cost>
void add_edge(WeightedGraph<Cost> &g, int from, int to, Cost cost) {
    g[from].emplace_back(from, to, cost);
}

int main() {
    int R, C, r1, c1, r2, c2;
    cin >> R >> C >> r1 >> c1 >> r2 >> c2;

    WeightedGraph<int> g(R * C);
    auto id = [&](int r, int c) {
        return r * C + c;
    };
    auto valid = [&](int r, int c) {
        return r >= 0 && r < R && c >= 0 && c < C;
    };

    int dr[] = {-1, 0, 1, 0};
    for (int i = 0; i < R; i++) {
        for (int j = 0; j < C; j++) {
            for (int d = 0; d < 4; d++) {
                int r = i + dr[d];
                int c = j + dr[(d + 1) % 4];
                if (valid(r, c)) {
                    add_edge(g, id(i, j), id(r, c), 1);
                }
            }
            add_edge(g, id(i, j), id(0, j), 1);
            add_edge(g, id(i, j), id(i, 0), 1);
            add_edge(g, id(i, j), id(R - 1, j), 1);
            add_edge(g, id(i, j), id(i, C - 1), 1);
        }
    }
    auto costs = dijkstra(g, id(r1, c1));
    vector<pair<int,int>> ws;
    for(int i = 0 ; i < costs.size() ; i++){
        ws.push_back({costs[i], i});
    }
    sort(ws.begin(), ws.end());
    vector<int> dp(R * C);
    dp[id(r1, c1)] = 1;
    for( auto I : ws ){
        int i = I.second;
        for(auto j : g[i]){
            if( j.cost + costs[i] == costs[j.to]) {
                dp[j.to] += dp[i];
                dp[j.to] %= 1000000007;
            }
        }
    }
    cout << costs[id(r2, c2)] << " " << dp[id(r2, c2)] << endl;
}
accuracy: 1
time_ms: 70
memory_kb: 24244
final_rank: 16

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 505

struct Info{
	Info(int arg_row,int arg_col,ll arg_count){
		row = arg_row;
		col = arg_col;
		count = arg_count;
	}
	int row,col;
	ll count;
};

struct Data{
	Data(){
		row = col = 0;
		sum_cost = 0;
	}

	Data(int arg_row,int arg_col,int arg_sum_cost){
		row = arg_row;
		col = arg_col;
		sum_cost = arg_sum_cost;
	}
	ll row,col,sum_cost;
};

int H,W;
int start_row,start_col,goal_row,goal_col;
int diff_row[4] = {-1,0,0,1},diff_col[4] = {0,-1,1,0};
ll dp[NUM][NUM];
ll min_cost[NUM][NUM];


bool rangeCheck(int row,int col){
	if(row >= 0 && row <= H-1 && col >= 0 && col <= W-1){
		return true;
	}else{
		return false;
	}
}

int find(vector<Info> V,int row,int col){

    int	ret = -1;

	for(int i = 0; i < V.size(); i++){
		if(V[i].row == row && V[i].col == col){
			return i;
		}
	}

	return ret;
}

int main(){

	scanf("%d %d",&H,&W);
	scanf("%d %d %d %d",&start_row,&start_col,&goal_row,&goal_col);

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			min_cost[row][col] = HUGE_NUM; //そのマスに到達する際の最小コスト
			dp[row][col] = 0; //そのマスに到達する経路の総数
		}
	}

	min_cost[start_row][start_col] = 0;
	dp[start_row][start_col] = 1;

	queue<Data> Q;
	Q.push(Data(start_row,start_col,0));

	Data data;
	int adj_row,adj_col,tmp_index;
	vector<Info> V;

	while(!Q.empty()){

		data = Q.front();
		Q.pop();

		//今回のマスから行けるマスと、そこへの経路数を数える
		V.clear();

		//まずは上下左右
		for(int i = 0; i < 4; i++){

			adj_row = data.row+diff_row[i];
			adj_col = data.col+diff_col[i];

			if(!rangeCheck(adj_row,adj_col))continue;

			V.push_back(Info(adj_row,adj_col,1));
		}

		//行の左端(今左端にいるなら、コストがかかるだけ移動は無駄)
		if(data.col != 0){

			tmp_index = find(V,data.row,0);
			if(tmp_index == -1){

				V.push_back(Info(data.row,0,1));
			}else{

				V[tmp_index].count++;
			}
		}

		//行の右端
		if(data.col != W-1){

			tmp_index = find(V,data.row,W-1);
			if(tmp_index == -1){

				V.push_back(Info(data.row,W-1,1));
			}else{

				V[tmp_index].count++;
			}
		}

		//列の上端
		if(data.row != 0){

			tmp_index = find(V,0,data.col);
			if(tmp_index == -1){

				V.push_back(Info(0,data.col,1));
			}else{

				V[tmp_index].count++;
			}
		}

		//列の下端
		if(data.row != H-1){

			tmp_index = find(V,H-1,data.col);
			if(tmp_index == -1){

				V.push_back(Info(H-1,data.col,1));
			}else{

				V[tmp_index].count++;
			}
		}

		for(int i = 0; i < V.size(); i++){

			if(min_cost[V[i].row][V[i].col] > data.sum_cost+1){ //最小値を更新する場合

				min_cost[V[i].row][V[i].col] = data.sum_cost+1;
				dp[V[i].row][V[i].col] = dp[data.row][data.col]*V[i].count;
				dp[V[i].row][V[i].col] %= MOD;
				Q.push(Data(V[i].row,V[i].col,data.sum_cost+1));

			}else if(min_cost[V[i].row][V[i].col] == data.sum_cost+1){ //同点で最小値の場合

				dp[V[i].row][V[i].col] += dp[data.row][data.col]*V[i].count;
				dp[V[i].row][V[i].col] %= MOD;
			}
		}
	}

	printf("%lld %lld\n",min_cost[goal_row][goal_col],dp[goal_row][goal_col]);

	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 7032
final_rank: 10

code_snippet: #include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
using namespace std;
  
#define rep(i,a,n) for(int (i)=(a); (i)<(n); (i)++)
#define repq(i,a,n) for(int (i)=(a); (i)<=(n); (i)++)
#define repr(i,a,n) for(int (i)=(a); (i)>=(n); (i)--)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define int long long int
  
template<typename T> void chmax(T &a, T b) {a = max(a, b);}
template<typename T> void chmin(T &a, T b) {a = min(a, b);}
template<typename T> void chadd(T &a, T b) {a = a + b;}
  
typedef pair<int, int> pii;
typedef long long ll;
  
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const ll INF = 1001001001001001LL;
const ll MOD = 1000000007LL;
 
pair<int, int> dp[510][510];
const pair<int, int> INFII(INF, -1);
  
void update(pair<int, int> &A, pair<int, int> B) {
    B.first = B.first + 1;
    if(A.first > B.first) A = B;
    else if(A.first == B.first) {
        (A.second += B.second) %= MOD;
    }
}
 
struct Elem {
    int x, y, ans, cnt;
};
 
signed main() {
    int R, C, sx, sy, tx, ty; cin >> R >> C >> sx >> sy >> tx >> ty;
    fill(dp[0], dp[R], INFII);
    dp[sx][sy] = make_pair(0, 1);
 
    queue<Elem> que;
    que.push(Elem{sx, sy, 0, 1});
 
    const int ex[] = {-1, 0, -1, R-1};
    const int ey[] = {0, -1, C-1, -1};
    for(int step=0; step<R+C; step++) {
        set< pair<int, int> > checked;
        while(que.size()) {
            Elem cur = que.front(); que.pop();
            // 隣接
            for(int k=0; k<4; k++) {
                int nx = cur.x + dx[k], ny = cur.y + dy[k];
                if(nx < 0 || ny < 0 || nx >= R || ny >= C) continue;
                if(dp[nx][ny].first < dp[cur.x][cur.y].first + 1) continue;
                update(dp[nx][ny], dp[cur.x][cur.y]);
                checked.insert(make_pair(nx, ny));
            }
 
            // テレポート
            for(int k=0; k<4; k++) {
                int nx = (ex[k] < 0 ? cur.x : ex[k]);
                int ny = (ey[k] < 0 ? cur.y : ey[k]);
                if(dp[nx][ny].first < dp[cur.x][cur.y].first + 1) continue;
                update(dp[nx][ny], dp[cur.x][cur.y]);
                checked.insert(make_pair(nx, ny));
            }
        }
         
        for(auto x : checked) {
            int nx, ny; tie(nx, ny) = x;
            int vl, vr; tie(vl, vr) = dp[nx][ny];
            que.push(Elem{nx, ny, vl, vr});
        }
    }
 
    int ans1, ans2;
    tie(ans1, ans2) = dp[tx][ty];
    printf("%lld %lld\n", ans1, ans2);
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 7120
final_rank: 11

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 100010

ll dp[600][600];
int dist[600][600];

int main(){
  int w, h, sx, sy, gx, gy;

  cin >> w >> h >> sx >> sy >> gx >> gy;

  for(int i=0;i<h;i++)
    for(int j=0;j<w;j++)
      dist[i][j] = INF;

  queue<pair<pair<int,int>,pair<int,int> > > q1;

  q1.push({{sy, sx}, {h, w}});
  dp[h][w] = 1;
  
  for(int i=0;q1.size();i++){
    queue<pair<pair<int,int>,pair<int,int> > > q2;

    while(q1.size()){
      auto p = q1.front(); q1.pop();
      int y = p.first.first;
      int x = p.first.second;
      ll cost = dp[p.second.first][p.second.second];

      if(y < 0 || h <= y || x < 0 || w <= x) continue;
      if(dist[y][x] < i) continue;
      
      if(dist[y][x] == i){
        dp[y][x] = (dp[y][x] + cost)%mod;
        continue;
      }

      dp[y][x] = cost;
      dist[y][x] = i;

      int dx[8] = {0,0,1,-1,1,1,-1,-1};
      int dy[8] = {1,-1,0,0,1,-1,1,-1};
      for(int i=0;i<4;i++){
        q2.push({{y+dy[i], x+dx[i]},{y,x}});
      }
      q2.push({{0,x},{y,x}});
      q2.push({{y,0},{y,x}});
      q2.push({{h-1,x},{y,x}});
      q2.push({{y,w-1},{y,x}});
    }

    q1 = q2;
  }

  cout << dist[gy][gx] << " " << dp[gy][gx] << endl;
  
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 6380
final_rank: 9

code_snippet: #include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<b;i++)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,a) for(auto &i:a)
#define all(x) (x).begin(),(x).end()
#pragma GCC optimize ("-O3")
using namespace std; void _main(); int main() { cin.tie(0); ios::sync_with_stdio(false); _main(); }
typedef long long ll; const int inf = INT_MAX / 2; const ll infl = 1LL << 60;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a = b; return 1; } return 0; }
//---------------------------------------------------------------------------------------------------
template<int MOD> struct ModInt {
    static const int Mod = MOD; unsigned x; ModInt() : x(0) { }
    ModInt(signed sig) { x = sig < 0 ? sig % MOD + MOD : sig % MOD; }
    ModInt(signed long long sig) { x = sig < 0 ? sig % MOD + MOD : sig % MOD; }
    int get() const { return (int)x; }
    ModInt &operator+=(ModInt that) { if ((x += that.x) >= MOD) x -= MOD; return *this; }
    ModInt &operator-=(ModInt that) { if ((x += MOD - that.x) >= MOD) x -= MOD; return *this; }
    ModInt &operator*=(ModInt that) { x = (unsigned long long)x * that.x % MOD; return *this; }
    ModInt &operator/=(ModInt that) { return *this *= that.inverse(); }
    ModInt operator+(ModInt that) const { return ModInt(*this) += that; }
    ModInt operator-(ModInt that) const { return ModInt(*this) -= that; }
    ModInt operator*(ModInt that) const { return ModInt(*this) *= that; }
    ModInt operator/(ModInt that) const { return ModInt(*this) /= that; }
    ModInt inverse() const {
        long long a = x, b = MOD, u = 1, v = 0;
        while (b) { long long t = a / b; a -= t * b; std::swap(a, b); u -= t * v; std::swap(u, v); }
        return ModInt(u);
    }
    bool operator==(ModInt that) const { return x == that.x; }
    bool operator!=(ModInt that) const { return x != that.x; }
    ModInt operator-() const { ModInt t; t.x = x == 0 ? 0 : Mod - x; return t; }
};
template<int MOD> ostream& operator<<(ostream& st, const ModInt<MOD> a) { st << a.get(); return st; };
template<int MOD> ModInt<MOD> operator^(ModInt<MOD> a, unsigned long long k) {
    ModInt<MOD> r = 1; while (k) { if (k & 1) r *= a; a *= a; k >>= 1; } return r;
}
typedef ModInt<1000000007> mint;
template<typename T> using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
/*---------------------------------------------------------------------------------------------------
　　　　　　　　　　　 ∧＿∧  
　　　　　 ∧＿∧ 　（´<_｀ ）　 Welcome to My Coding Space!
　　　　 （ ´_ゝ`）　/　 ⌒i     
　　　　／　　　＼　 　 |　|     
　　　 /　　 /￣￣￣￣/　　|  
　 ＿_(__ﾆつ/　    ＿/ .| .|＿＿＿＿  
　 　　　＼/＿＿＿＿/　（u　⊃  
---------------------------------------------------------------------------------------------------*/



int W, H, ax, ay, bx, by;
int dst[505][505], vis[505][505]; mint dp[505][505];
int dx[4] = { 0, 1, 0, -1 }, dy[4] = { -1, 0, 1, 0 };
//---------------------------------------------------------------------------------------------------
void _main() {
    cin >> W >> H >> ax >> ay >> bx >> by;

    rep(y, 0, H) rep(x, 0, W) dst[y][x] = inf;
    min_priority_queue<pair<int, int>> que;

    dst[ay][ax] = 0;
    dp[ay][ax] = 1;
    que.push({ 0, ay * 1010 + ax });
    while (!que.empty()) {
        auto q = que.top(); que.pop();

        int x = q.second % 1010;
        int y = q.second / 1010;
        int c = q.first;

        if (vis[y][x]) continue;
        vis[y][x] = 1;

        if (y == by and x == bx) {
            cout << c << " " << dp[y][x] << endl;
            return;
        }

        vector<pair<int, int>> nxt;
        rep(d, 0, 4) nxt.push_back({ x + dx[d], y + dy[d] });
        nxt.push_back({ 0, y });
        nxt.push_back({ W - 1, y });
        nxt.push_back({ x, 0 });
        nxt.push_back({ x, H - 1 });

        fore(p, nxt) {
            int xx, yy;
            tie(xx, yy) = p;

            if (xx < 0 or W <= xx or yy < 0 or H <= yy) continue;

            if (c + 1 < dst[yy][xx]) {
                dst[yy][xx] = c + 1;
                dp[yy][xx] = dp[y][x];
                que.push({ c + 1, yy * 1010 + xx });
            }
            else if (c + 1 == dst[yy][xx]) dp[yy][xx] += dp[y][x];
        }
    }
}
accuracy: 1
time_ms: 20
memory_kb: 5372
final_rank: 6

code_snippet: #include "bits/stdc++.h"
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int INF = 1e9;
const ll LINF = 1e18;
template<class S,class T> ostream& operator << (ostream& out,const pair<S,T>& o){ out << "(" << o.first << "," << o.second << ")"; return out; }
template<class T> ostream& operator << (ostream& out,const vector<T> V){ for(int i = 0; i < V.size(); i++){ out << V[i]; if(i!=V.size()-1) out << " ";} return out; }
template<class T> ostream& operator << (ostream& out,const vector<vector<T> > Mat){ for(int i = 0; i < Mat.size(); i++) { if(i != 0) out << endl; out << Mat[i];} return out; }
template<class S,class T> ostream& operator << (ostream& out,const map<S,T> mp){ out << "{ "; for(auto it = mp.begin(); it != mp.end(); it++){ out << it->first << ":" << it->second; if(mp.size()-1 != distance(mp.begin(),it)) out << ", "; } out << " }"; return out; }

/*
 <url:https://onlinejudge.u-aizu.ac.jp/services/room.html#ACPC2018Day2/problems/D>
 問題文============================================================
 =================================================================
 解説=============================================================
 ================================================================
 */

const ll MOD = 1e9+7;
int d[4] = {1,0,-1,0};
struct edge{
    ll x,y,dist,sum;
    edge(ll x = 0,ll y = 0,ll dist = 0,ll sum = 0)
    :x(x),y(y),dist(dist),sum(sum){}
    bool operator < (const edge& e) const{
        return this->dist < e.dist;
    }
    bool operator > (const edge& e) const{
        return this->dist > e.dist;
    }

};
vector<ll> solve(){
    vector<ll> res;
    ll R,C,ai,aj,bi,bj;
    cin >> R >> C >> ai >> aj >> bi >> bj;
    vector<vector<pll>> dist(R,vector<pll>(C,{LINF,0}));
    priority_queue<edge,vector<edge>,greater<edge>> pq;
    pq.push(edge(ai,aj,0,1));
    dist[ai][aj] = {0,1};
    while(pq.size()){
        edge state = pq.top(); pq.pop();
        state.sum = dist[state.x][state.y].second;
        for(int k = 0; k < 4;k++){
            ll nx = state.x + d[k];
            ll ny = state.y + d[k^1];
            
            if(nx < 0 || nx >= R || ny < 0 || ny >= C) continue;
            if(dist[nx][ny].first > state.dist + 1){
                dist[nx][ny] = {state.dist+1,state.sum};
                pq.push(edge(nx,ny,state.dist+1,state.sum));
            }else if(dist[nx][ny].first == state.dist + 1){
                (dist[nx][ny].second += state.sum)%=MOD;
            }
        }
        {
            ll nx = state.x; ll ny = 0;
            
            if(nx < 0 || nx >= R || ny < 0 || ny >= C) continue;
            if(dist[nx][ny].first > state.dist + 1){
                dist[nx][ny] = {state.dist+1,state.sum};
                pq.push(edge(nx,ny,state.dist+1,state.sum));
            }else if(dist[nx][ny].first == state.dist + 1){
                (dist[nx][ny].second += state.sum)%=MOD;
            }
        }
        {
            ll nx = state.x; ll ny = C-1;
            
            if(nx < 0 || nx >= R || ny < 0 || ny >= C) continue;
            if(dist[nx][ny].first > state.dist + 1){
                dist[nx][ny] = {state.dist+1,state.sum};
                pq.push(edge(nx,ny,state.dist+1,state.sum));
            }else if(dist[nx][ny].first == state.dist + 1){
                (dist[nx][ny].second += state.sum)%=MOD;
            }
        }
        {
            ll nx = 0; ll ny = state.y;
            
            if(nx < 0 || nx >= R || ny < 0 || ny >= C) continue;
            if(dist[nx][ny].first > state.dist + 1){
                dist[nx][ny] = {state.dist+1,state.sum};
                pq.push(edge(nx,ny,state.dist+1,state.sum));
            }else if(dist[nx][ny].first == state.dist + 1){
                (dist[nx][ny].second += state.sum)%=MOD;
            }
        }
        {
            ll nx = R-1; ll ny = state.y;
            
            if(nx < 0 || nx >= R || ny < 0 || ny >= C) continue;
            if(dist[nx][ny].first > state.dist + 1){
                dist[nx][ny] = {state.dist+1,state.sum};
                pq.push(edge(nx,ny,state.dist+1,state.sum));
            } else if(dist[nx][ny].first == state.dist + 1){
                (dist[nx][ny].second += state.sum)%=MOD;
            }
        }
    }
    
    res = vector<ll>{dist[bi][bj].first,dist[bi][bj].second};
    return res;
}
int main(void) {
    cin.tie(0); ios_base::sync_with_stdio(false);
    cout << solve() << endl;
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 5956
final_rank: 2

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

int h,w,ax,ay,bx,by;
vector<int> G[500*500+1];
int px[]={0,1,0,-1};
int py[]={1,0,-1,0};
long long int mod=1e9+7;
int comb(int x,int y){
  int ans=x+y*w;
  return ans;
}

typedef pair<int, int> P;
vector<pair<int,long long int> > dist(500*500+1,make_pair(1e9,0));

void dijkstra(long long int s){
  priority_queue<P,vector<P>,greater<P> > que;
  dist[s]=make_pair(0,1);
  que.push(P(0,s));
  while(!que.empty()){
    P p=que.top();
    que.pop();
    long long int v=p.second;
    long long int d=p.first;
    if(dist[v].first<d)continue;
    for(int i=0;i<G[v].size();i++){
      long long int d2=d+1;
      if(dist[G[v][i]].first>d2){
        dist[G[v][i]].first=d2;
        dist[G[v][i]].second=dist[v].second;
        dist[G[v][i]].second%mod;
        que.push(P(dist[G[v][i]].first,G[v][i]));
      }else if(dist[G[v][i]].first==d2){
        dist[G[v][i]].second+=dist[v].second;
        dist[G[v][i]].second%=mod;
      }
    }
  }
}

int main(){
  cin>>h>>w>>ay>>ax>>by>>bx;
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      for(int k=0;k<4;k++){
        int nx=j+px[k];
        int ny=i+py[k];
        if(nx>=0&&ny>=0&&nx<w&&ny<h){
          G[comb(j,i)].push_back(comb(nx,ny));
        }
      }
      int nx=0;
      int ny=i;
      if(nx>=0&&ny>=0&&nx<w&&ny<h){
        G[comb(j,i)].push_back(comb(nx,ny));
      }
      nx=w-1;
      ny=i;
      if(nx>=0&&ny>=0&&nx<w&&ny<h){
        G[comb(j,i)].push_back(comb(nx,ny));
      }
      nx=j;
      ny=0;
      if(nx>=0&&ny>=0&&nx<w&&ny<h){
        G[comb(j,i)].push_back(comb(nx,ny));
      }
      nx=j;
      ny=h-1;
      if(nx>=0&&ny>=0&&nx<w&&ny<h){
        G[comb(j,i)].push_back(comb(nx,ny));
      }
    }
  }
  dijkstra(comb(ax,ay));
  //for(int i=0;i<h*w;i++)cout<<dist[i].first<<" "<<dist[i].second<<endl;
  cout<<dist[comb(bx,by)].first<<" "<<dist[comb(bx,by)].second%mod<<endl;
}
accuracy: 1
time_ms: 50
memory_kb: 21312
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1000000007;

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

int main() {
  int h, w, ai, aj, bi, bj;
  cin >> h >> w >> ai >> aj >> bi >> bj;

  vector<vector<pair<ll, ll>>> r(h, vector<pair<ll, ll>>(w, {1e9, 0}));

  queue<pair<int, int>> q;
  q.push({ai, aj});
  r[ai][aj] = {0, 1};
  while (!q.empty()) {
    auto p = q.front();
    q.pop();

    vector<pair<int, int>> next;
    for (int i = 0; i < 4; i++) {
      next.push_back({p.first + dy[i], p.second + dx[i]});
    }
    next.push_back({p.first, 0});
    next.push_back({p.first, w - 1});
    next.push_back({0, p.second});
    next.push_back({h - 1, p.second});

    for (auto e : next) {
      if (e == p || e.first < 0 || h <= e.first || e.second < 0 || w <= e.second) {
        continue;
      }

      if (r[p.first][p.second].first + 1 == r[e.first][e.second].first) {
        r[e.first][e.second].second += r[p.first][p.second].second;
        r[e.first][e.second].second %= mod;
      } else if (r[p.first][p.second].first + 1 < r[e.first][e.second].first) {
        r[e.first][e.second].first = r[p.first][p.second].first + 1;
        r[e.first][e.second].second = r[p.first][p.second].second;
        q.push(e);
      }
    }
  }

  // for (auto ee : r) {
  //   for (auto e : ee) {
  //     cerr << e.first << "," << e.second << " ";
  //   }
  //   cerr << endl;
  // }

  cout << r[bi][bj].first << " " << r[bi][bj].second << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 5728
final_rank: 7

code_snippet: #include<bits/stdc++.h>
#define range(i,a,b) for(int i = (a); i < (b); i++)
#define rep(i,b) for(int i = 0; i < (b); i++)
#define all(a) (a).begin(), (a).end()
#define show(x)  cerr << #x << " = " << (x) << endl;
using namespace std;

template<typename T>
ostream& operator << (ostream& os, vector<T>& v){
	rep(i,v.size()){ os << v[i] << (i == v.size() - 1 ? "" : " "); } return os;
}
template<typename T>
istream& operator >> (istream& is, vector<T>& v){
	for(T& x: v){ is >> x; } return is;
}

const int MAX = 510;
const long long M = 1000000007;

int r, c, ay, ax, by, bx;
int dis[MAX][MAX];
long long cnt[MAX][MAX];

struct P{
	int y, x;
	int cost;
	P(int y, int x, int cost) : y(y), x(x), cost(cost) { }
	bool operator < ( const P &right ) const {
		return cost < right.cost;
	}
	bool operator > ( const P &right ) const {
		return cost > right.cost;
	}
};

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

int shortestPath(){
	priority_queue<P, vector<P>, greater<P>> q;
	q.emplace(P(ay, ax, 0));

	while(not q.empty()){
		P cur = q.top(); q.pop();

		if(dis[cur.y][cur.x] != INT_MAX) continue;
		dis[cur.y][cur.x] = cur.cost;

		if(cur.y == by and cur.x == bx) continue;

		//cout << cur.y << ' ' << cur.x << endl;
		rep(d,4){ // 隣接
			int ny = cur.y + dy[d];
			int nx = cur.x + dx[d];
			if(ny < 0 || ny >= r || nx < 0 || nx >= c) continue;
			if(dis[ny][nx] <= cur.cost + 1) continue;
			q.emplace(ny, nx, cur.cost + 1);
		}
		rep(d,4){
			int ny = cur.y, nx = cur.x;
			if(dy[d] == 1) ny = r - 1;
			if(dy[d] == -1) ny = 0;

			if(dx[d] == 1) nx = c - 1;
			if(dx[d] == -1) nx = 0;

			if(dis[ny][nx] <= cur.cost + 1) continue;
			q.emplace(ny, nx, cur.cost + 1);
		}
	}

	//rep(i,r){ rep(j,c){ cout << dis[i][j] << ' '; } cout << endl; }
	
	return dis[by][bx];
}

long long solve(){
	priority_queue<P, vector<P>, greater<P>> q;
	q.emplace(P(ay, ax, 0));

	cnt[ay][ax] = 1;

	bool used[MAX][MAX] = {};
	while(not q.empty()){
		P cur = q.top(); q.pop();

		if(cur.y == by and cur.x == bx) continue;
		if(used[cur.y][cur.x]) continue;
		used[cur.y][cur.x] = true;

		//cout << "cur " << cur.y << ' ' << cur.x << endl;

		rep(d,4){ // 隣接
			int ny = cur.y + dy[d];
			int nx = cur.x + dx[d];
			if(ny < 0 || ny >= r || nx < 0 || nx >= c) continue;
			if(dis[ny][nx] < cur.cost + 1) continue;
			//cout << dy[d] << ' ' << dx[d] << endl;
			//cout << ny << ' ' << nx << ' ' << cur.y << ' ' << cur.x << endl;
			(cnt[ny][nx] += cnt[cur.y][cur.x]) %= M;
			q.emplace(ny, nx, cur.cost + 1);
		}
		rep(d,4){
			int ny = cur.y, nx = cur.x;
			if(dy[d] == 1) ny = r - 1;
			if(dy[d] == -1) ny = 0;

			if(dx[d] == 1) nx = c - 1;
			if(dx[d] == -1) nx = 0;

			if(dis[ny][nx] < cur.cost + 1) continue;
			//cout << ny << ' ' << nx << ' ' << cur.y << ' ' << cur.x << endl;
			(cnt[ny][nx] += cnt[cur.y][cur.x]) %= M;
			q.emplace(ny, nx, cur.cost + 1);
		}
	}
	//rep(i,r){ rep(j,c){ cout << cnt[i][j] << ' '; } cout << endl; }

	return cnt[by][bx];
}

int main(){
	cin >> r >> c >> ay >> ax >> by >> bx;
	rep(i,MAX) rep(j,MAX) dis[i][j] = INT_MAX;

	shortestPath();
	cout << shortestPath() << ' ' << solve() << endl;
}
accuracy: 1
time_ms: 40
memory_kb: 6272
final_rank: 13

code_snippet: #include<iostream>
#include<iomanip>
#include<queue>
#include<string>
#include<stack>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<cassert>
#include<ctime>
#include<algorithm>
#include<utility>
#include<map>
#include<set>
#include<vector>
#include<functional>
#include<complex>

using namespace std;

typedef long long            ll;
typedef unsigned             ui;
typedef unsigned long long   ull;
typedef pair<int,int>        i_i;
typedef pair<ll,int>         ll_i;
typedef pair<ll,ll>          ll_ll;
typedef pair<double,int>     d_i;
typedef pair<double,double>  d_d;
typedef vector<int>          vi;
typedef vector<vector<int> > vii;

#ifdef DEBUG
#define dprintf      printf
#define dputs        puts
#define dout(x)      cout<<#x" = "<<(x)<<endl
#define darray(x,n)  {int i;rep(i,n)cout<<#x"["<<i<<"] = "<<*((x)+i)<<endl;}
#define dloop(i,s,g) for(int (i)=(s);(i)<(g);(i)++)
#define drep(i,n)    for(int (i)=0;(i)<(n);(i)++)
#define dstop()      scanf("%*c")
#else
#define dprintf      (1)?0:printf
#define dputs        (1)?0:puts
#define dout(x)
#define darray(x,n)
#define dloop(i,s,g) if(int i=0){}else
#define drep(i,n)    if(int i=0){}else
#define dstop()
#endif

#define F    first
#define S    second
#define pb   push_back
#define mp   make_pair

#define loop(i,s,g) for((i)=(s);(i)<(g);(i)++)
#define rep(i,n)    for((i)=0;(i)<(n);(i)++)
#define all(x)      (x.begin(),x.end())
#define in(T,...) T __VA_ARGS__; impl(__VA_ARGS__)
#define array(T,id,n) T id[(n)]; for(int i=0;i<(n);i++)cin>>id[i]
#define putv(n)     cout<<(n)<<endl

//#define int long long
#ifndef int
#define INF __INT32_MAX__
#else
#define INF __INT64_MAX__
#endif

void impl(){};
template <typename T,typename... TS >
void impl(T &head,TS &... tail)
{
  cin>>head;
  impl(tail ...);
}

ll dp[600][600][600];

signed main(void)
{
  bool judge=false;
  int dx[4]={0,1,0,-1};
  int dy[4]={1,0,-1,0};
  int i,x,y;
  ll mod = 1e9+7;
  in(int,R,C,ai,aj,bi,bj);
  dp[0][ai][aj]=1;
  rep(i,520){
    rep(x,R){
      rep(y,C){
        dp[i][x][y]%=mod;
        int j;
        rep(j,4){
          if(0<=x+dx[j]&&x+dx[j]<R&&
             0<=y+dy[j]&&y+dy[j]<C){
            dp[i+1][x+dx[j]][y+dy[j]]+=dp[i][x][y];
          }
        }
        dp[i+1][0  ][y  ]+=dp[i][x][y];
        dp[i+1][R-1][y  ]+=dp[i][x][y];
        dp[i+1][x  ][0  ]+=dp[i][x][y];
        dp[i+1][x  ][C-1]+=dp[i][x][y];
        if(x==bi&&y==bj&&
           dp[i][bi][bj]!=0){
          judge=true;
        }
      }
    }
    if(judge)
      break;
  }
  printf("%d %lld\n",i,dp[i][bi][bj]%mod);
    return 0;
}
accuracy: 1
time_ms: 260
memory_kb: 454036
final_rank: 19

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

long long di[4] = {0, -1, 0, 1};
long long dj[4] = {1, 0, -1, 0};
//(R, C)
//(i, j)
//array[][]

#define INF 1000000000000
const long long MOD = 1000000007;

// 🔴
// O(ElogE)

// pq<pair> はfirstが大きい順に出てくるのですか？
// s:= 開始ノード  v:= 頂点数  adjlist:= 隣接リスト (first:= コスト   second:= 行先)
vector<long long> dijk(long long s, long long v, vector<vector<pair<long long, long long> > > &adjlist){

    priority_queue <pair<long long, long long> > wait;
    vector<long long> result(v, INF);

    //スタート地点を追加
    result[s] = 0;
    wait.push(make_pair(0, s));

    //ダイクストラ本体
    while(!wait.empty()){    //waitが空になるまで

        long long nowpoint = wait.top().second;
        long long nowcost = -wait.top().first;
        wait.pop();

        if(result[nowpoint] < nowcost) continue;

        //今いる頂点と隣接しているすべての頂点をなめる
        for(long long i = 0; i < adjlist[nowpoint].size(); i++){

            long long nextpoint = adjlist[nowpoint][i].second;
            long long nextcost = nowcost + adjlist[nowpoint][i].first;
            //現時点より安く到達できそうであれば、結果を更新して優先度付きキューに格納
            if(result[nextpoint] > nextcost){
                result[nextpoint] = nextcost;
                wait.push(make_pair(-nextcost, nextpoint));
            }
        }
    }
    
    return result;         //結果列を返す
}

int main(){

    long long R, C, si, sj, gi, gj; cin >> R >> C >> si >> sj >> gi >> gj;
    
    vector<vector<long long> > MAP(R, vector<long long> (C));
    long long n = 0;        //頂点数
    for(long long i = 0; i < R; i++){
        for(long long j = 0; j < C; j++){
            MAP[i][j] = n;
            n++;
        }
    }

    vector<vector<pair<long long, long long> > > adj(n);

    for(long long i = 0; i < R; i++){
        for(long long j = 0; j < C; j++){

            long long now = MAP[i][j];
            
            //上下左右
            for(long long h = 0; h < 4; h++){
                long long ni = i + di[h];
                long long nj = j + dj[h];
                if(ni < 0 || R <= ni || nj < 0 || C <= nj) continue;

                long long next = MAP[ni][nj];
                adj[now].push_back({1, next});
            }

            //特殊辺
            long long next = MAP[i][0];
            if(now != next) adj[now].push_back({1, next});
            next = MAP[i][C - 1];
            if(now != next) adj[now].push_back({1, next});
            next = MAP[0][j];
            if(now != next) adj[now].push_back({1, next});
            next = MAP[R - 1][j];
            if(now != next) adj[now].push_back({1, next});                             
        }
    }

    vector<long long> result(n);
    long long S = MAP[si][sj];
    long long G = MAP[gi][gj];
    result = dijk(S, n, adj);
    //cout << result[G] << endl;
    

    //辺削除
    vector<bool> used(n, false);
    vector<long long> dp(n, 0);

    dp[S] = 1;
    used[S] = true;
    queue<long long> q;
    q.push(S);

    while(!q.empty()){
        
        long long now = q.front();
        q.pop();
        for(auto e : adj[now]){

            int next = e.second;
            if(result[next] - result[now] != 1) continue;
            dp[next] += dp[now];
            dp[next] %= MOD;
            if(!used[next]){
                q.push(next);
                used[next] = true;
            }
        }
    }

    cout << result[G] << " " << dp[G] << endl;
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 37208
final_rank: 17