Problem:
D：歪みの国 - Country In Distortion -
物語
アリスはすっかり退屈していました。いつも一緒に遊んでいる白ウサギが、トランプ城へ出かけているからです。（あーあ、こんなことなら一緒に出かければよかったわ。）とアリスは思いました。けれども、ここは歪みの国。そうやすやすと出かけては、ひどく疲れてしまいます。どういうことかというと—
白ウサギは困っていました。トランプ城への道中、ちょっとだけ道を間違えてしまったのです。（困ったなあ。一度戻って、道を良く知っているアリスに案内してもらうことにしよう。）と白ウサギは考えました。それにしても、白ウサギはとっても疲れているみたい。白ウサギは懐中時計を見ながら、
「なんだってこの国の道は、通る度に長さが変わったように感じるんだ！この道、さっきは100メートルくらいに感じたけど、今度は1キロはあるんじゃないか？それも、通り抜けるのにかかる時間はほとんど変わってないって言うのに！」
と叫んでいます。そう、ここは歪みの国。まさに、時々刻々と道が歪み続ける不思議な国なのです。
やっとの思いでアリスの家に着いた白ウサギが開口一番、
「ごめんよアリス。トランプ城まで、道案内をお願いできるかい。」
と言うと、退屈のあまりオフトゥンに突っ伏してしていたアリスは元気に飛び起きました。
「もちろんよ！一緒に行きましょう！」
嬉しい一方で、疲れた様子の白ウサギを見て（でも、あまりに疲れてしまうのは悪いわね。）と思ったアリスは、家の奥から歪みの国の地図を取り出してきました。
「さあ、トランプ城までの疲れない道のりを探すわ！」
問題
n
頂点と
m
辺からなる無向グラフが与えられる。各辺
i
の移動にかかる時間は
t_i
で表される。また、初めの体感移動速度として
v_0
が与えられる。その後、辺を1本通る度に体感移動速度が変化する。辺を
j
本通った後の体感移動速度は、整数
a, b, c
をパラメータとして以下の式で与えられる。
v_j = (a \times v_{j-1} + b)
mod
c
辺
i
を速度
v_j
で通ると体感移動距離が
t_i \times v_j
となる。なお、歪みの国では体感移動速度が0でも移動可能であり、そのときの体感移動距離は0である。
今、頂点
1
から出発し頂点
n
を経由して頂点
1
に戻ってくるような経路を考える。考えうる経路の中で体感移動距離の総和を最小化せよ。
入力形式
n
m
x_1
y_1
t_1
...
x_m
y_m
t_m
v_0
a
b
c
入力は全て整数からなる。
1行目には、グラフの頂点数と辺数を表す
n,m
がこの順で空白区切りで与えられる。
続く
m
行のうち
i
行目には、
i
番目の辺が接続する2頂点
x_i,y_i
と、通過するのにかかる時間
t_i
がこの順で空白区切りで与えられる。
m+2
行目には、初速度を表す
v_0
が与えられる。
m+3
行目には、速度の計算式のパラメータ
a,b,c
がこの順に空白区切りで与えられる。
制約
各値は整数である。
2 \leq n \leq 500
1 \leq m \leq min\{5000, n(n - 1) / 2\}
各
i=1,...,m
について
1 \leq x_i < y_i \leq n
である。また、
1 \leq i < j \leq m
を満たす
i, j
について、
x_i \neq x_j
または
y_i \neq y_j
である。つまり自己ループおよび多重辺はない。
各
i=1,...,m
について
1 \leq t_i \leq 10^8
0 \leq v_0 \leq 49
0 < a < c, 0 \leq b < c, v_0 < c \leq 50
グラフは連結である。すなわち任意の2頂点間に経路があることが保証される。
出力形式
体感移動距離の総和の最小値を1行に出力せよ。
入力例1
4 4
1 2 3
2 3 1
2 4 5
3 4 2
5
4 5 6
出力例1
34
入力例2
6 5
1 2 1
2 3 100
3 4 2
4 5 200
5 6 1
3
4 5 9
出力例2
341
通過するのに時間がかかる辺 (2,3) と (4,5) を通る前に、短い時間で通れる道を往復して、なるべく速度を落とした方が体感移動距離は短い。
入力例3
10 9
1 2 74150933
2 3 13214145
3 4 45636411
4 5 90778512
5 6 85676138
6 7 60913535
7 8 43917556
8 9 47519690
9 10 56593754
33
37 41 47
出力例3
23049391759
体感移動距離が非常に長くなる場合もある。

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
using std::cout;
using std::cin;
using std::endl;
using ll=long long;
using ld=long double;
ll ILL=2167167167167167167;
const int INF=2100000000;
const ll mod=1e9+7;
#define rep(i,a) for (ll i=0;i<a;i++)
#define all(p) p.begin(),p.end()
template<class T> using _pq = priority_queue<T, vector<T>, greater<T>>;
template<class T> ll LB(vector<T> &v,T a){return lower_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> ll UB(vector<T> &v,T a){return upper_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> bool chmin(T &a,const T &b){if(a>b){a=b;return 1;}else return 0;}
template<class T> bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}else return 0;}
template<class T> void So(vector<T> &v) {sort(v.begin(),v.end());}
template<class T> void Sore(vector<T> &v) {sort(v.begin(),v.end(),[](T x,T y){return x>y;});}
void yneos(bool a){if(a) cout<<"Yes\n"; else cout<<"No\n";}
template<class T> void vec_out(vector<T> &p){for(int i=0;i<(int)(p.size());i++){if(i) cout<<" ";cout<<p[i];}cout<<"\n";}
template<class T> T min(vector<T> &a){assert(!a.empty());T ans=a[0];for(auto &x:a) chmin(ans,x);return ans;}
template<class T> T max(vector<T> &a){assert(!a.empty());T ans=a[0];for(auto &x:a) chmax(ans,x);return ans;}

using len_type=ll;
struct edge{
    ll to;
    len_type length;
};

len_type dijkstra_movement(edge e,int from,len_type t){
    return t+e.length;
}


vector<len_type> dijkstra(vector<vector<edge>> &G,int start,len_type inf){
    int M=G.size();
    assert(M>start&&start>=0);
    vector<len_type> seen(M,inf);
    seen[start]=0;
    priority_queue<pair<len_type,int>,vector<pair<len_type,int>>,greater<pair<len_type,int>>> pq;
    pq.push({0,start});
    while(!pq.empty()){
        len_type time;
        int ver;
        tie(time,ver)=pq.top();
        pq.pop();
        if(seen[ver]<time) continue;
        for(edge x:G[ver]){
            len_type T=dijkstra_movement(x,ver,time);
            if(T<seen[x.to]){
                pq.push({T,x.to});
                seen[x.to]=T;
            }
        }
    }
    return seen;
}


void solve();
// oddloop
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	int t=1;
	//cin>>t;
	rep(i,t) solve();
}

void solve(){
	int n,m;
	cin>>n>>m;
	vector<ll> x(m),y(m),t(m);
	rep(i,m) cin>>x[i]>>y[i]>>t[i],x[i]--,y[i]--;
	rep(i,m) x.push_back(y[i]),y.push_back(x[i]),t.push_back(t[i]);
	rep(i,m*2) x.push_back(x[i]+n),y.push_back(y[i]+n),t.push_back(t[i]);
	ll v_0,a,b,c;
	cin>>v_0>>a>>b>>c;
	vector<vector<edge>> G(n*2*c);
	rep(i,m*4){
		rep(j,c){
			G[x[i]*c+j].push_back({y[i]*c+(a*j+b)%c,t[i]*j});
		}
	}
	rep(i,c){
		G[(n-1)*c+i].push_back({(2*n-1)*c+i,0});
	}
	auto seen=dijkstra(G,v_0,ILL);
	ll ans=ILL;
	rep(i,c) chmin(ans,seen[n*c+i]);
	cout<<ans<<"\n";
}
accuracy: 1
time_ms: 40
memory_kb: 29128
final_rank: 12

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
//using namespace atcoder;
#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
using namespace std;
 
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<int, int> pii;
typedef pair<long long, long long> PLL;
typedef pair<int, PII> TIII;
 
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
 
 
#define FOR(i, s, n) for (int i = s; i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define trav(a, x) for (auto &a : x)
#define all(x) x.begin(), x.end()
 
#define MOD 1000000007
 
template<class T1, class T2> inline bool chmax(T1 &a, T2 b) {if (a < b) {a = b; return true;} return false;}
template<class T1, class T2> inline bool chmin(T1 &a, T2 b) {if (a > b) {a = b; return true;} return false;}
const double EPS = 1e-8, PI = acos(-1);
const double pi = 3.141592653589793238462643383279;
//ここから編集    
typedef string::const_iterator State;
ll GCD(ll a, ll b){
  return (b==0)?a:GCD(b, a%b);
}
ll LCM(ll a, ll b){
  return a/GCD(a, b) * b;
}
template< int mod >
struct ModInt {
  int x;
 
  ModInt() : x(0) {}
 
  ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}
 
  ModInt &operator+=(const ModInt &p) {
    if((x += p.x) >= mod) x -= mod;
    return *this;
  }
 
  ModInt &operator-=(const ModInt &p) {
    if((x += mod - p.x) >= mod) x -= mod;
    return *this;
  }
 
  ModInt &operator*=(const ModInt &p) {
    x = (int) (1LL * x * p.x % mod);
    return *this;
  }
 
  ModInt &operator/=(const ModInt &p) {
    *this *= p.inverse();
    return *this;
  }
 
  ModInt operator-() const { return ModInt(-x); }
 
  ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; }
 
  ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; }
 
  ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; }
 
  ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; }
 
  bool operator==(const ModInt &p) const { return x == p.x; }
 
  bool operator!=(const ModInt &p) const { return x != p.x; }
 
  ModInt inverse() const {
    int a = x, b = mod, u = 1, v = 0, t;
    while(b > 0) {
      t = a / b;
      swap(a -= t * b, b);
      swap(u -= t * v, v);
    }
    return ModInt(u);
  }
 
  ModInt pow(int64_t n) const {
    ModInt ret(1), mul(x);
    while(n > 0) {
      if(n & 1) ret *= mul;
      mul *= mul;
      n >>= 1;
    }
    return ret;
  }
 
  friend ostream &operator<<(ostream &os, const ModInt &p) {
    return os << p.x;
  }
 
  friend istream &operator>>(istream &is, ModInt &a) {
    int64_t t;
    is >> t;
    a = ModInt< mod >(t);
    return (is);
  }
 
  static int get_mod() { return mod; }
};
 
using modint = ModInt< 1000000007 >;
template< typename T >
struct Combination {
  vector< T > _fact, _rfact, _inv;
 
  Combination(int sz) : _fact(sz + 1), _rfact(sz + 1), _inv(sz + 1) {
    _fact[0] = _rfact[sz] = _inv[0] = 1;
    for(int i = 1; i <= sz; i++) _fact[i] = _fact[i - 1] * i;
    _rfact[sz] /= _fact[sz];
    for(int i = sz - 1; i >= 0; i--) _rfact[i] = _rfact[i + 1] * (i + 1);
    for(int i = 1; i <= sz; i++) _inv[i] = _rfact[i] * _fact[i - 1];
  }
 
  inline T fact(int k) const { return _fact[k]; }
 
  inline T rfact(int k) const { return _rfact[k]; }
 
  inline T inv(int k) const { return _inv[k]; }
 
  T P(int n, int r) const {
    if(r < 0 || n < r) return 0;
    return fact(n) * rfact(n - r);
  }
 
  T C(int p, int q) const {
    if(q < 0 || p < q) return 0;
    return fact(p) * rfact(q) * rfact(p - q);
  }
 
  T H(int n, int r) const {
    if(n < 0 || r < 0) return (0);
    return r == 0 ? 1 : C(n + r - 1, r);
  }
};
 
ll modpow(ll x, ll n, ll mod) {
  ll res = 1;
  x %= mod;
  if(x == 0) return 0;
  while(n) {
    if(n&1) res = (res * x) % mod;
    x = (x * x) % mod;
    n >>= 1;
  }
  return res;
} 
inline long long mod(long long a, long long m) {
    return (a % m + m) % m;
}
template<typename T> 
struct BIT{
  int N;
  std::vector<T> node;
  BIT(){}
  BIT(int n){
    N = n;
    node.resize(N+10);
  }
  void build(int n) {
    N = n;
    node.resize(N+10);
  }
  /* a: 1-indexed */
  void add(int a, T x){
    for(int i=a; i<(int)node.size(); i += i & -i) node[i] += x;
  }

  /* [1, a] */
  T sum(int a){
    T res = 0;
    for(int x=a; x>0; x -= x & -x) res += node[x];
    return res;
  }

  /* [l, r] */
  T rangesum(int l, int r){
    return sum(r) - sum(l-1);
  }

  /* 
    a1+a2+...+aw >= valとなるような最小のwを返す
    @verify https://codeforces.com/contest/992/problem/E
  */
  int lower_bound(T val) {
    if(val < 0) return 0;

    int res = 0;
    int n = 1; 
    while (n < N) n *= 2;

    T tv=0;
    for (int k = n; k > 0; k /= 2) {
      if(res + k < N && node[res + k] < val){
        val -= node[res+k];
        res += k;
      }
    }
    return res+1; 
  }
};
struct UnionFind{
  std::vector<int> par;
  std::vector<int> siz;

  UnionFind(int sz_): par(sz_), siz(sz_) {
    for(int i=0; i<sz_; ++i) par[i] = i, siz[i] = 1;
  }

  void init(int sz_){
    par.resize(sz_);
    siz.resize(sz_);
    for(int i=0; i<sz_; ++i) par[i] = i, siz[i] = 1;
  }

  int root(int x){
    if(x == par[x]) return x;
    return par[x] = root(par[x]);
  }

  bool merge(int x, int y){
    x = root(x), y = root(y);
    if(x == y) return false;
    if(siz[x] < siz[y]) std::swap(x, y);
    siz[x] += siz[y];
    par[y] = x;
    return true;
  }

  bool issame(int x, int y){
    return root(x) == root(y);
  }

  int size(int x){
    return siz[root(x)];
  }
};
struct RollingHash{

    using ull = unsigned long long;
    const ull mod = (1ULL << 61) - 1;
    const ull MASK30 = (1ULL << 30) - 1;
    const ull MASK31 = (1ULL << 31) - 1;

    const ull MASK61 = mod;

    ull base;
    int n;
    vector<ull> hash, pow;

    RollingHash(const string &s)
    {
        random_device rnd;
        mt19937_64 mt(rnd());
        base = 1001;
        
        n = (int)s.size();
        hash.assign(n+1, 0);
        pow.assign(n+1, 1);
        
        for(int i=0; i<n; i++){
            hash[i+1] = calc_mod(mul(hash[i], base) + s[i]);
            pow[i+1] = calc_mod(mul(pow[i], base));
        }
    }

    ull calc_mod(ull x){
        ull xu = x >> 61;
        ull xd = x & MASK61;
        ull res = xu + xd;
        if(res >= mod) res -= mod;
        return res;
    }

    ull mul(ull a, ull b){
        ull au = a >> 31;
        ull ad = a & MASK31;
        ull bu = b >> 31;
        ull bd = b & MASK31;
        ull mid = ad * bu + au * bd;
        ull midu = mid >> 30;
        ull midd = mid & MASK30;
        return calc_mod(au * bu * 2 + midu + (midd << 31) + ad * bd);
    }

    //[l,r)のハッシュ値
    inline ull get(int l, int r){
        ull res = calc_mod(hash[r] + mod*3-mul(hash[l], pow[r-l]));
        return res;
    }
    //string tのハッシュ値
    inline ull get(string t){
        ull res = 0;
        for(int i=0; i<t.size(); i++){
            res = calc_mod(mul(res, base)+t[i]);
        }
        return res;
    }
    //string s中のtの数をカウント
    inline int count(string t) {
        if(t.size() > n) return 0;
        auto hs = get(t);
        int res = 0;
        for(int i=0; i<n-t.size()+1; i++){
            if(get(i, i+t.size()) == hs) res++; 
        }
        return res;
    }

    /* 
        concat 
        @verify https://codeforces.com/problemset/problem/514/C
    */
    inline ull concat(ull h1, ull h2, int h2len){
      return calc_mod(h2 + mul(h1, pow[h2len]));
    }

    // LCPを求める S[a:] T[b:]
    inline int LCP(int a, int b){
        int len = min((int)hash.size()-a, (int)hash.size()-b);
        
        int lb = -1, ub = len;
        while(ub-lb>1){
            int mid = (lb+ub)/2;

            if(get(a, a+mid) == get(b, b+mid)) lb = mid;
            else ub = mid;
        }
        return lb;
    }
};
ll dp[510][55][2];
vector<vector<pair<ll,ll>>> g(510);
int main() {  
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(12);

  int n, m; cin >> n >> m;
  
  REP(i,m) {
    int a, b, c; cin >> a >> b >> c;
    a--; b--;
    g[a].push_back({b, c});
    g[b].push_back({a, c});
  }
  int v0, a, b, c; cin >> v0 >> a >> b >> c;
  REP(i,510) REP(j,55) REP(k,2) dp[i][j][k] = (1LL<<60);
  dp[0][v0][0] = 0;
  priority_queue<pair<ll,tuple<ll,ll,ll>>, vector<pair<ll,tuple<ll,ll,ll>>>, greater<pair<ll,tuple<ll,ll,ll>>>> pq;
  pq.push({0, {v0, 0, 0}});
  while(pq.size()) {
    auto[cost, p] = pq.top(); pq.pop();
    auto[vnow, v, f] = p;
    if(dp[v][vnow][f] < cost) continue;
    for(auto[u, t] : g[v]) {
      int vnxt = (a * vnow + b) % c;
      int nxtf = (f | (u == n-1));
      if(dp[u][vnxt][nxtf] > dp[v][vnow][f] + t * vnow) {
        dp[u][vnxt][nxtf] = dp[v][vnow][f] + t*vnow;
        pq.push({dp[u][vnxt][nxtf], {vnxt, u, nxtf}});
      }
    }
  }
  ll ans = (1LL<<60);
  REP(i,c) ans = min(ans, dp[0][i][1]);
  cout << ans << endl;
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 12888
final_rank: 7

code_snippet: #line 2 "/home/yuruhiya/programming/library/template/template.cpp"
#include <bits/stdc++.h>
#line 4 "/home/yuruhiya/programming/library/template/constants.cpp"
#include <string_view>
#line 7 "/home/yuruhiya/programming/library/template/constants.cpp"

#define rep(i, n) for (int i = 0; i < (n); ++i)
#define FOR(i, m, n) for (int i = (m); i < (n); ++i)
#define rrep(i, n) for (int i = (n)-1; i >= 0; --i)
#define rfor(i, m, n) for (int i = (m); i >= (n); --i)
#define unless(c) if (!(c))
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define range_it(a, l, r) (a).begin() + (l), (a).begin() + (r)

using namespace std;
using ll = long long;
using LD = long double;
using VB = vector<bool>;
using VVB = vector<VB>;
using VI = vector<int>;
using VVI = vector<VI>;
using VL = vector<ll>;
using VVL = vector<VL>;
using VS = vector<string>;
using VD = vector<LD>;
using PII = pair<int, int>;
using VP = vector<PII>;
using PLL = pair<ll, ll>;
using VPL = vector<PLL>;
template <class T> using PQ = priority_queue<T>;
template <class T> using PQS = priority_queue<T, vector<T>, greater<T>>;
constexpr int inf = 1000000000;
constexpr long long inf_ll = 1000000000000000000ll, MOD = 1000000007;
constexpr long double PI = 3.14159265358979323846, EPS = 1e-12;
namespace CharacterClass {
	constexpr string_view
	    digit = "0123456789",
	    xdigit = "0123456789ABCDEFabcdef", lower = "abcdefghijklmnopqrstuvwxyz",
	    upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
	    alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
	    alnum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
	    word = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz",
	    punct = R"(!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)",
	    graph =
	        R"(!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~)",
	    print =
	        R"( !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~)",
	    blank = " \t", space = " \t\n\r\f\v";
}  // namespace CharacterClass
#line 7 "/home/yuruhiya/programming/library/template/Input.cpp"
using namespace std;

#ifdef _WIN32
#define getchar_unlocked _getchar_nolock
#define putchar_unlocked _putchar_nolock
#define fwrite_unlocked fwrite
#define fflush_unlocked fflush
#endif
class Scanner {
	static int gc() {
		return getchar_unlocked();
	}
	static char next_char() {
		char c;
		read(c);
		return c;
	}
	template <class T> static void read(T& v) {
		cin >> v;
	}
	static void read(char& v) {
		while (isspace(v = gc()))
			;
	}
	static void read(bool& v) {
		v = next_char() != '0';
	}
	static void read(string& v) {
		v.clear();
		for (char c = next_char(); !isspace(c); c = gc()) v += c;
	}
	static void read(int& v) {
		v = 0;
		bool neg = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c); c = gc()) v = v * 10 + (c - '0');
		if (neg) v = -v;
	}
	static void read(long long& v) {
		v = 0;
		bool neg = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c); c = gc()) v = v * 10 + (c - '0');
		if (neg) v = -v;
	}
	static void read(double& v) {
		v = 0;
		double dp = 1;
		bool neg = false, after_dp = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c) || c == '.'; c = gc()) {
			if (c == '.') {
				after_dp = true;
			} else if (after_dp) {
				v += (c - '0') * (dp *= 0.1);
			} else {
				v = v * 10 + (c - '0');
			}
		}
		if (neg) v = -v;
	}
	static void read(long double& v) {
		v = 0;
		long double dp = 1;
		bool neg = false, after_dp = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c) || c == '.'; c = gc()) {
			if (c == '.') {
				after_dp = true;
			} else if (after_dp) {
				v += (c - '0') * (dp *= 0.1);
			} else {
				v = v * 10 + (c - '0');
			}
		}
		if (neg) v = -v;
	}
	template <class T, class U> static void read(pair<T, U>& v) {
		read(v.first);
		read(v.second);
	}
	template <class T> static void read(vector<T>& v) {
		for (auto& e : v) read(e);
	}
	template <size_t N = 0, class T> static void read_tuple_impl(T& v) {
		if constexpr (N < tuple_size_v<T>) {
			read(get<N>(v));
			read_tuple_impl<N + 1>(v);
		}
	}
	template <class... T> static void read(tuple<T...>& v) {
		read_tuple_impl(v);
	}
	struct ReadVectorHelper {
		size_t n;
		ReadVectorHelper(size_t _n) : n(_n) {}
		template <class T> operator vector<T>() {
			vector<T> v(n);
			read(v);
			return v;
		}
	};
	struct Read2DVectorHelper {
		size_t n, m;
		Read2DVectorHelper(const pair<size_t, size_t>& nm) : n(nm.first), m(nm.second) {}
		template <class T> operator vector<vector<T>>() {
			vector<vector<T>> v(n, vector<T>(m));
			read(v);
			return v;
		}
	};

public:
	string read_line() const {
		string v;
		for (char c = gc(); c != '\n' && c != '\0'; c = gc()) v += c;
		return v;
	}
	template <class T> T read() const {
		T v;
		read(v);
		return v;
	}
	template <class T> vector<T> read_vector(size_t n) const {
		vector<T> a(n);
		read(a);
		return a;
	}
	template <class T> operator T() const {
		return read<T>();
	}
	int operator--(int) const {
		return read<int>() - 1;
	}
	ReadVectorHelper operator[](size_t n) const {
		return ReadVectorHelper(n);
	}
	Read2DVectorHelper operator[](const pair<size_t, size_t>& nm) const {
		return Read2DVectorHelper(nm);
	}
	void operator()() const {}
	template <class H, class... T> void operator()(H&& h, T&&... t) const {
		read(h);
		operator()(forward<T>(t)...);
	}

private:
	template <template <class...> class, class...> struct Multiple;
	template <template <class...> class V, class Head, class... Tail>
	struct Multiple<V, Head, Tail...> {
		template <class... Args> using vec = V<vector<Head>, Args...>;
		using type = typename Multiple<vec, Tail...>::type;
	};
	template <template <class...> class V> struct Multiple<V> { using type = V<>; };
	template <class... T> using multiple_t = typename Multiple<tuple, T...>::type;
	template <size_t N = 0, class T> void multiple_impl(T& t) const {
		if constexpr (N < tuple_size_v<T>) {
			auto& vec = get<N>(t);
			using V = typename remove_reference_t<decltype(vec)>::value_type;
			vec.push_back(read<V>());
			multiple_impl<N + 1>(t);
		}
	}

public:
	template <class... T> auto multiple(size_t h) const {
		multiple_t<T...> result;
		while (h--) multiple_impl(result);
		return result;
	}
} in;
#define inputs(T, ...) \
	T __VA_ARGS__;     \
	in(__VA_ARGS__)
#define ini(...) inputs(int, __VA_ARGS__)
#define inl(...) inputs(long long, __VA_ARGS__)
#define ins(...) inputs(string, __VA_ARGS__)
#line 7 "/home/yuruhiya/programming/library/template/Output.cpp"
#include <charconv>
#line 10 "/home/yuruhiya/programming/library/template/Output.cpp"
using namespace std;

struct BoolStr {
	const char *t, *f;
	BoolStr(const char* _t, const char* _f) : t(_t), f(_f) {}
} Yes("Yes", "No"), yes("yes", "no"), YES("YES", "NO"), Int("1", "0");
struct DivStr {
	const char *d, *l;
	DivStr(const char* _d, const char* _l) : d(_d), l(_l) {}
} spc(" ", "\n"), no_spc("", "\n"), end_line("\n", "\n"), comma(",", "\n"),
    no_endl(" ", "");
class Printer {
	BoolStr B{Yes};
	DivStr D{spc};

public:
	void print(int v) const {
		char buf[12]{};
		if (auto [ptr, e] = to_chars(begin(buf), end(buf), v); e == errc{}) {
			fwrite(buf, sizeof(char), ptr - buf, stdout);
		} else {
			assert(false);
		}
	}
	void print(long long v) const {
		char buf[21]{};
		if (auto [ptr, e] = to_chars(begin(buf), end(buf), v); e == errc{}) {
			fwrite(buf, sizeof(char), ptr - buf, stdout);
		} else {
			assert(false);
		}
	}
	void print(bool v) const {
		print(v ? B.t : B.f);
	}
	void print(vector<bool>::reference v) const {
		print(v ? B.t : B.f);
	}
	void print(char v) const {
		putchar_unlocked(v);
	}
	void print(const char* v) const {
		fwrite_unlocked(v, 1, strlen(v), stdout);
	}
	void print(double v) const {
		printf("%.20f", v);
	}
	void print(long double v) const {
		printf("%.20Lf", v);
	}
	template <class T> void print(const T& v) const {
		cout << v;
	}
	template <class T, class U> void print(const pair<T, U>& v) const {
		print(v.first);
		print(D.d);
		print(v.second);
	}
	template <class InputIterater>
	void print_range(const InputIterater& begin, const InputIterater& end) const {
		for (InputIterater i = begin; i != end; ++i) {
			if (i != begin) print(D.d);
			print(*i);
		}
	}
	template <class T> void print(const vector<T>& v) const {
		print_range(v.begin(), v.end());
	}
	template <class T, size_t N> void print(const array<T, N>& v) const {
		print_range(v.begin(), v.end());
	}
	template <class T> void print(const vector<vector<T>>& v) const {
		for (size_t i = 0; i < v.size(); ++i) {
			if (i) print(D.l);
			print(v[i]);
		}
	}

	Printer() = default;
	Printer(const BoolStr& _boolstr, const DivStr& _divstr) : B(_boolstr), D(_divstr) {}
	Printer& operator()() {
		print(D.l);
		return *this;
	}
	template <class H> Printer& operator()(H&& h) {
		print(h);
		print(D.l);
		return *this;
	}
	template <class H, class... T> Printer& operator()(H&& h, T&&... t) {
		print(h);
		print(D.d);
		return operator()(forward<T>(t)...);
	}
	template <class InputIterator>
	Printer& range(const InputIterator& begin, const InputIterator& end) {
		print_range(begin, end);
		print(D.l);
		return *this;
	}
	template <class T> Printer& range(const T& a) {
		range(a.begin(), a.end());
		return *this;
	}
	template <class... T> void exit(T&&... t) {
		operator()(forward<T>(t)...);
		std::exit(EXIT_SUCCESS);
	}
	Printer& flush() {
		fflush_unlocked(stdout);
		return *this;
	}
	Printer& set(const BoolStr& b) {
		B = b;
		return *this;
	}
	Printer& set(const DivStr& d) {
		D = d;
		return *this;
	}
	Printer& set(const char* t, const char* f) {
		B = BoolStr(t, f);
		return *this;
	}
} out;
#line 3 "/home/yuruhiya/programming/library/template/Step.cpp"
using namespace std;

template <class T> struct Step {
	using value_type = T;

	class iterator {
		value_type a, b, c;

	public:
		constexpr iterator() : a(value_type()), b(value_type()), c(value_type()) {}
		constexpr iterator(value_type _b, value_type _c, value_type _s)
		    : a(_b), b(_c), c(_s) {}
		constexpr iterator& operator++() {
			--b;
			a += c;
			return *this;
		}
		constexpr iterator operator++(int) {
			iterator tmp = *this;
			--b;
			a += c;
			return tmp;
		}
		constexpr const value_type& operator*() const {
			return a;
		}
		constexpr const value_type* operator->() const {
			return &a;
		}
		constexpr bool operator==(const iterator& i) const {
			return b == i.b;
		}
		constexpr bool operator!=(const iterator& i) const {
			return !(b == i.b);
		}
		constexpr value_type start() const {
			return a;
		}
		constexpr value_type size() const {
			return b;
		}
		constexpr value_type step() const {
			return c;
		}
	};
	constexpr Step(value_type b, value_type c, value_type s) : be(b, c, s) {}
	constexpr iterator begin() const {
		return be;
	}
	constexpr iterator end() const {
		return en;
	}
	constexpr value_type start() const {
		return be.start();
	}
	constexpr value_type size() const {
		return be.size();
	}
	constexpr value_type step() const {
		return be.step();
	}
	constexpr value_type sum() const {
		return start() * size() + step() * (size() * (size() - 1) / 2);
	}
	operator vector<value_type>() const {
		return to_a();
	}
	auto to_a() const {
		vector<value_type> result;
		result.reserve(size());
		for (auto i : *this) {
			result.push_back(i);
		}
		return result;
	}

private:
	iterator be, en;
};
template <class T> constexpr auto step(T a) {
	return Step<T>(0, a, 1);
}
template <class T> constexpr auto step(T a, T b) {
	return Step<T>(a, b - a, 1);
}
template <class T> constexpr auto step(T a, T b, T c) {
	return Step<T>(a, a < b ? (b - a - 1) / c + 1 : 0, c);
}
#line 8 "/home/yuruhiya/programming/library/template/Ruby.cpp"
using namespace std;

template <class F> struct Callable {
	F func;
	Callable(const F& f) : func(f) {}
};
template <class T, class F> auto operator|(const T& v, const Callable<F>& c) {
	return c.func(v);
}

struct Sort_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v), f);
			return v;
		});
	}
	template <class T> friend auto operator|(T v, [[maybe_unused]] const Sort_impl& c) {
		sort(begin(v), end(v));
		return v;
	}
} Sort;
struct SortBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v),
			     [&](const auto& i, const auto& j) { return f(i) < f(j); });
			return v;
		});
	}
} SortBy;
struct RSort_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(rbegin(v), rend(v), f);
			return v;
		});
	}
	template <class T> friend auto operator|(T v, [[maybe_unused]] const RSort_impl& c) {
		sort(rbegin(v), rend(v));
		return v;
	}
} RSort;
struct RSortBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v),
			     [&](const auto& i, const auto& j) { return f(i) > f(j); });
			return v;
		});
	}
} RSortBy;
struct Reverse_impl {
	template <class T> friend auto operator|(T v, const Reverse_impl& c) {
		reverse(begin(v), end(v));
		return v;
	}
} Reverse;
struct Unique_impl {
	template <class T> friend auto operator|(T v, const Unique_impl& c) {
		v.erase(unique(begin(v), end(v), end(v)));
		return v;
	}
} Unique;
struct Uniq_impl {
	template <class T> friend auto operator|(T v, const Uniq_impl& c) {
		sort(begin(v), end(v));
		v.erase(unique(begin(v), end(v)), end(v));
		return v;
	}
} Uniq;
struct Rotate_impl {
	auto operator()(int&& left) {
		return Callable([&](auto v) {
			int s = static_cast<int>(size(v));
			assert(-s <= left && left <= s);
			if (0 <= left) {
				rotate(begin(v), begin(v) + left, end(v));
			} else {
				rotate(begin(v), end(v) + left, end(v));
			}
			return v;
		});
	}
} Rotate;
struct Max_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) { return *max_element(begin(v), end(v), f); });
	}
	template <class T> friend auto operator|(T v, const Max_impl& c) {
		return *max_element(begin(v), end(v));
	}
} Max;
struct Min_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) { return *min_element(begin(v), end(v), f); });
	}
	template <class T> friend auto operator|(T v, const Min_impl& c) {
		return *min_element(begin(v), end(v));
	}
} Min;
struct MaxPos_impl {
	template <class T> friend auto operator|(T v, const MaxPos_impl& c) {
		return max_element(begin(v), end(v)) - begin(v);
	}
} MaxPos;
struct MinPos_impl {
	template <class T> friend auto operator|(T v, const MinPos_impl& c) {
		return min_element(begin(v), end(v)) - begin(v);
	}
} MinPos;
struct MaxBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto max_it = begin(v);
			auto max_val = f(*max_it);
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); max_val < val) {
					max_it = it;
					max_val = val;
				}
			}
			return *max_it;
		});
	}
} MaxBy;
struct MinBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto min_it = begin(v);
			auto min_val = f(*min_it);
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); min_val > val) {
					min_it = it;
					min_val = val;
				}
			}
			return *min_it;
		});
	}
} MinBy;
struct MaxOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto max_val = f(*begin(v));
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); max_val < val) {
					max_val = val;
				}
			}
			return max_val;
		});
	}
} MaxOf;
struct MinOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto min_val = f(*begin(v));
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); min_val > val) {
					min_val = val;
				}
			}
			return min_val;
		});
	}
} MinOf;
struct Count_impl {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) { return count(begin(v), end(v), val); });
	}
} Count;
struct CountIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) { return count_if(begin(v), end(v), f); });
	}
} CountIf;
struct Index_impl {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) -> optional<int> {
			auto result = find(begin(v), end(v), val);
			return result != end(v) ? optional(result - begin(v)) : nullopt;
		});
	}
	template <class V> auto operator()(const V& val, size_t i) {
		return Callable([&](auto v) -> optional<int> {
			auto result = find(next(begin(v), i), end(v), val);
			return result != end(v) ? optional(result - begin(v)) : nullopt;
		});
	}
} Index;
struct IndexIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) -> optional<int> {
			auto result = find_if(begin(v), end(v), f);
			return result != end(v) ? optional(result - begin(v)) : nullopt;
		});
	}
} IndexIf;
struct FindIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) -> optional<typename decltype(v)::value_type> {
			auto result = find_if(begin(v), end(v), f);
			return result != end(v) ? optional(*result) : nullopt;
		});
	}
} FindIf;
struct Sum_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			return accumulate(next(begin(v)), end(v), f(*begin(v)),
			                  [&](const auto& a, const auto& b) { return a + f(b); });
		});
	}
	template <class T> friend auto operator|(T v, const Sum_impl& c) {
		return accumulate(begin(v), end(v), typename T::value_type{});
	}
} Sum;
struct Includes {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) { return find(begin(v), end(v), val) != end(v); });
	}
} Includes;
struct IncludesIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) { return find_if(begin(v), end(v), f) != end(v); });
	}
} IncludesIf;
struct RemoveIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) {
			v.erase(remove_if(begin(v), end(v), f), end(v));
			return v;
		});
	}
} RemoveIf;
struct Each_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				f(i);
			}
		});
	}
} Each;
struct Select_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			using value_type = typename decltype(v)::value_type;
			vector<value_type> result;
			for (const auto& i : v) {
				if (f(i)) result.push_back(i);
			}
			return result;
		});
	}
} Select;
struct Map_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			using result_type = invoke_result_t<F, typename decltype(v)::value_type>;
			vector<result_type> result;
			result.reserve(size(v));
			for (const auto& i : v) {
				result.push_back(f(i));
			}
			return result;
		});
	}
} Map;
struct Indexed_impl {
	template <class T> friend auto operator|(const T& v, Indexed_impl& c) {
		using value_type = typename T::value_type;
		vector<pair<value_type, int>> result;
		result.reserve(size(v));
		int index = 0;
		for (const auto& i : v) {
			result.emplace_back(i, index++);
		}
		return result;
	}
} Indexed;
struct AllOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (!f(i)) return false;
			}
			return true;
		});
	}
} AllOf;
struct AnyOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (f(i)) return true;
			}
			return false;
		});
	}
} AnyOf;
struct NoneOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (f(i)) return false;
			}
			return true;
		});
	}
} NoneOf;

struct Tally_impl {
	template <class F> auto operator()(size_t max_val) {
		return Callable([&](auto v) {
			vector<size_t> result(max_val);
			for (const auto& i : v) {
				result[static_cast<size_t>(i)]++;
			}
			return result;
		});
	}
	template <class T, class value_type = typename T::value_type>
	friend auto operator|(const T& v, Tally_impl& c) {
		map<value_type, size_t> result;
		for (const auto& i : v) {
			result[i]++;
		}
		return result;
	}
} Tally;

template <class T> auto operator*(const vector<T>& a, size_t n) {
	T result;
	for (size_t i = 0; i < n; ++i) {
		result.insert(result.end(), a.begin(), a.end());
	}
	return result;
}
auto operator*(string a, size_t n) {
	string result;
	for (size_t i = 0; i < n; ++i) {
		result += a;
	}
	return result;
}
template <class T, class U> auto& operator<<(vector<T>& a, const U& b) {
	a.insert(a.end(), all(b));
	return a;
}
template <class T> auto& operator<<(string& a, const T& b) {
	a.insert(a.end(), all(b));
	return a;
}
template <class T, class U> auto operator+(vector<T> a, const U& b) {
	a << b;
	return a;
}
template <class T> auto operator+(string a, const T& b) {
	a << b;
	return a;
}
#line 7 "/home/yuruhiya/programming/library/template/functions.cpp"
using namespace std;

template <class T = long long> constexpr T TEN(size_t n) {
	T result = 1;
	for (size_t i = 0; i < n; ++i) result *= 10;
	return result;
}
template <class T, class U,
          enable_if_t<is_integral_v<T> && is_integral_v<U>, nullptr_t> = nullptr>
constexpr auto div_ceil(T n, U m) {
	return (n + m - 1) / m;
}
template <class T, class U> constexpr auto div_ceil2(T n, U m) {
	return div_ceil(n, m) * m;
}
template <class T> constexpr T triangle(T n) {
	return (n & 1) ? (n + 1) / 2 * n : n / 2 * (n + 1);
}
template <class T> constexpr T nC2(T n) {
	return (n & 1) ? (n - 1) / 2 * n : n / 2 * (n - 1);
}
template <class T, class U> constexpr auto middle(const T& l, const U& r) {
	return l + (r - l) / 2;
}
template <class T, class U, class V>
constexpr bool in_range(const T& v, const U& lower, const V& upper) {
	return lower <= v && v < upper;
}
template <class T, enable_if_t<is_integral_v<T>, nullptr_t> = nullptr>
constexpr bool is_square(T n) {
	T s = sqrt(n);
	return s * s == n || (s + 1) * (s + 1) == n;
}
template <class T = long long> constexpr T BIT(int b) {
	return T(1) << b;
}
template <class T> constexpr int BIT(T x, int i) {
	return (x & (1 << i)) ? 1 : 0;
}
template <class T, class U, enable_if_t<is_integral_v<U>, nullptr_t> = nullptr>
constexpr T Pow(T a, U n) {
	assert(n >= 0);
	T result = 1;
	while (n > 0) {
		if (n & 1) {
			result *= a;
			n--;
		} else {
			a *= a;
			n >>= 1;
		}
	}
	return result;
}
template <class T, class U, enable_if_t<is_integral_v<U>, nullptr_t> = nullptr>
constexpr T Powmod(T a, U n, T mod) {
	assert(n >= 0);
	if (a > mod) a %= mod;
	T result = 1;
	while (n > 0) {
		if (n & 1) {
			result = result * a % mod;
			n--;
		} else {
			a = a * a % mod;
			n >>= 1;
		}
	}
	return result;
}
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 <class T> int sz(const T& v) {
	return v.size();
}
template <class T, class U> int lower_index(const T& a, const U& v) {
	return lower_bound(all(a), v) - a.begin();
}
template <class T, class U> int upper_index(const T& a, const U& v) {
	return upper_bound(all(a), v) - a.begin();
}
template <class T> auto Slice(const T& v, size_t i, size_t len) {
	return i < v.size() ? T(v.begin() + i, v.begin() + min(i + len, v.size())) : T();
}
template <class T, class U = typename T::value_type> U Gcdv(const T& v) {
	return accumulate(next(v.begin()), v.end(), U(*v.begin()), gcd<U, U>);
}
template <class T, class U = typename T::value_type> U Lcmv(const T& v) {
	return accumulate(next(v.begin()), v.end(), U(*v.begin()), lcm<U, U>);
}
namespace internal {
	template <class T, size_t N> auto make_vector(vector<int>& sizes, const T& init) {
		if constexpr (N == 1) {
			return vector(sizes[0], init);
		} else {
			int size = sizes[N - 1];
			sizes.pop_back();
			return vector(size, make_vector<T, N - 1>(sizes, init));
		}
	}
}  // namespace internal
template <class T, size_t N>
auto make_vector(const int (&sizes)[N], const T& init = T()) {
	vector s(rbegin(sizes), rend(sizes));
	return internal::make_vector<T, N>(s, init);
}
#line 9 "/home/yuruhiya/programming/library/template/template.cpp"
#if __has_include(<library/dump.hpp>)
#include <library/dump.hpp>
#define LOCAL
#else
#define dump(...) ((void)0)
#endif

template <class T> constexpr T oj_local(const T& oj, const T& local) {
#ifndef LOCAL
	return oj;
#else
	return local;
#endif
}
#line 5 "/home/yuruhiya/programming/library/Graph/GraphTemplate.cpp"
using namespace std;

using Weight = long long;
constexpr Weight INF = numeric_limits<Weight>::max();
struct Edge {
	int to;
	Weight cost;
	Edge() : to(-1), cost(-1) {}
	Edge(int _to, Weight _cost = 1) : to(_to), cost(_cost) {}
	friend bool operator<(const Edge& e1, const Edge& e2) {
		return e1.cost < e2.cost;
	}
	friend bool operator>(const Edge& e1, const Edge& e2) {
		return e1.cost > e2.cost;
	}
	friend ostream& operator<<(ostream& os, const Edge& e) {
		return os << "->" << e.to << '(' << e.cost << ')';
	}
};
using Graph = vector<vector<Edge>>;
struct Edge2 {
	int from, to;
	Weight cost;
	Edge2() : from(-1), to(-1), cost(0) {}
	Edge2(int _from, int _to, Weight _cost) : from(_from), to(_to), cost(_cost) {}
	friend bool operator<(const Edge2& e1, const Edge2& e2) {
		return e1.cost < e2.cost;
	}
	friend bool operator>(const Edge2& e1, const Edge2& e2) {
		return e1.cost > e2.cost;
	}
	friend ostream& operator<<(ostream& os, const Edge2& e) {
		return os << e.from << "->" << e.to << '(' << e.cost << ')';
	}
};
using Edges = vector<Edge2>;
using Matrix = vector<vector<Weight>>;
#line 5 "/home/yuruhiya/programming/library/Graph/Dijkstra.cpp"
using namespace std;

vector<Weight> Dijkstra(const Graph& graph, int s) {
	int V = graph.size();
	vector<Weight> dist(V, INF);
	dist[s] = 0;
	priority_queue<Edge, vector<Edge>, greater<Edge>> pq;
	pq.emplace(s, 0);
	while (!pq.empty()) {
		Edge p = pq.top();
		pq.pop();
		int v = p.to;
		if (dist[v] < p.cost) continue;
		for (auto e : graph[v]) {
			if (dist[e.to] > dist[v] + e.cost) {
				dist[e.to] = dist[v] + e.cost;
				pq.emplace(e.to, dist[e.to]);
			}
		}
	}
	return dist;
}
Weight Dijkstra(const Graph& graph, int s, int t) {
	int V = graph.size();
	vector<Weight> dist(V, INF);
	dist[s] = 0;
	priority_queue<Edge, vector<Edge>, greater<Edge>> pq;
	pq.emplace(s, 0);
	while (!pq.empty()) {
		Edge p = pq.top();
		pq.pop();
		int v = p.to;
		if (v == t) return dist[t];
		if (dist[v] < p.cost) continue;
		for (auto e : graph[v]) {
			if (dist[e.to] > dist[v] + e.cost) {
				dist[e.to] = dist[v] + e.cost;
				pq.emplace(e.to, dist[e.to]);
			}
		}
	}
	return dist[t];
}
#line 3 "a.cpp"

const int MAX_N = 501, MAX_S = 51;
int to_i(int v, int s, int f) {
	return v * MAX_S * 2 + s * 2 + f;
}

int main() {
	ini(n, m);
	auto [x, y, t] = in.multiple<int, int, ll>(m);
	rep(i, m) x[i]--, y[i]--;
	rep(i, m) {
		x.push_back(y[i]);
		y.push_back(x[i]);
		t.push_back(t[i]);
	}
	ini(v0, a, b, c);

	Graph g(MAX_N * MAX_S * 2);
	rep(i, m * 2) {
		rep(s, MAX_S) {
			int s2 = (s * a + b) % c;
			g[to_i(x[i], s, false)].emplace_back(to_i(y[i], s2, y[i] == n - 1), t[i] * s);
			g[to_i(x[i], s, true)].emplace_back(to_i(y[i], s2, true), t[i] * s);
		}
	}
	auto dist = Dijkstra(g, to_i(0, v0, false));
	ll ans = inf_ll;
	rep(s, MAX_S) {
		chmin(ans, dist[to_i(0, s, true)]);
	}
	out(ans);
}
accuracy: 1
time_ms: 30
memory_kb: 31536
final_rank: 14

code_snippet: #include <bits/stdc++.h>
#define inf (long long)(1e17)
using namespace std;

struct dat {
  long long n, v, t;
  dat(long long a = 0, long long b = 0, long long c = 0) : n(a), v(b), t(c) {}
  bool operator<(const dat &r) const {
    if (t != r.t) return t > r.t;
    if (n != r.n) return n < r.n;
    return v < r.v;
  }
};

using P = pair<int, int>;

int n, m, v0, a, b, c;
vector<vector<P>> g;

long long solve();

int main() {
  cin >> n >> m;
  g.resize(n);
  for (int i = 0; i < m; ++i) {
    int x, y, t;
    cin >> x >> y >> t;
    g[--x].emplace_back(--y, t);
    g[y].emplace_back(x, t);
  }
  cin >> v0 >> a >> b >> c;
  cout << solve() << endl;
  return 0;
}

long long solve() {
  auto dijk = [](int st, int go, int v0) {
    vector<vector<long long>> dp(n, vector<long long>(c, inf));
    priority_queue<dat> pq;
    dp[st][v0] = 0;
    pq.push(dat(st, v0, 0));
    while (pq.size()) {
      auto [now, nv, nt] = pq.top();
      pq.pop();
      if (dp[now][nv] != nt) continue;
      for (auto [to, time] : g[now]) {
        dat nxt(to, (a * nv + b) % c, nt + nv * time);
        if (dp[to][nxt.v] > nxt.t) {
          dp[to][nxt.v] = nxt.t;
          pq.push(nxt);
        }
      }
    }
    return dp[go];
  };
  long long res = inf;
  auto zero = dijk(0, n - 1, v0);
  for (int i = 0; i < c; ++i) {
    auto now = dijk(n - 1, 0, i);
    for (int j = 0; j < c; ++j) res = min(res, zero[i] + now[j]);
  }
  return res;
}
accuracy: 1
time_ms: 590
memory_kb: 8884
final_rank: 16

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <math.h>
#include <map>
using namespace std;
typedef long long int ll;


vector<pair<ll,ll>> g[501];

ll d[501][51][2];

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n,m; cin >> n >> m;
    for(int i=0;i<m;i++){
        int x,y,t; cin >> x >> y >> t;
        x--; y--;
        g[x].push_back({y,t});
        g[y].push_back({x,t});
    }
    int v; cin >> v;
    int a,b,c; cin >> a >> b >> c;
    for(int i=0;i<501;i++){
        for(int j=0;j<51;j++){
            for(int k=0;k<2;k++){
                d[i][j][k]=1e18;
            }
        }
    }
    d[0][v][0]=0;
    priority_queue<pair<pair<ll,int>,pair<int,int>>> pq;
    pq.push(make_pair(make_pair(0,0),make_pair(v,0)));
    while(pq.size()){
        auto p=pq.top(); pq.pop();
        if(-p.first.first!=d[p.first.second][p.second.first][p.second.second])continue;
        //cout << p.first.first << " " << p.first.second << " " << p.second.first << " "  << p.second.second << endl;    
        int s=p.first.second;
        for(auto t:g[s]){
            ll dis=(ll)t.second*(ll)(p.second.first);
            bool flag=p.second.second;
            if(t.first==n-1)flag=true;
            int nv=(a*p.second.first+b)%c;
            if(d[t.first][nv][flag]>-p.first.first+dis){
                d[t.first][nv][flag]=-p.first.first+dis;
                pq.push(make_pair(make_pair(p.first.first-dis,t.first),make_pair(nv,flag)));
            }
        }
    }
    ll res=1e18;
    for(int i=0;i<51;i++){
        res=min(res,d[0][i][1]);
    }
    cout << res << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 9644
final_rank: 3

code_snippet: #include <iostream>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <unordered_map>
#include <map>
#include <set>
#include <algorithm>
#include <queue>
#include <stack>
#include <functional>
#include <bitset>
#include <assert.h>
#include <unordered_map>
#include <fstream>
#include <ctime>
#include <complex>
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const int inf = 1<<30;
const ll linf = 1LL<<62;
const int MAX = 2020000;
ll dy[8] = {1,-1,0,0,1,-1,1,-1};
ll dx[8] = {0,0,1,-1,1,-1,-1,1};
const double pi = acos(-1);
const double eps = 1e-7;
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << "debug: " << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << "debug: " << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//const int mod = 1e9 + 7;
const int mod = 998244353;

int main(){
	int n,m; cin >> n >> m;
	vector<vpl> G(n);
	rep(i,m){
		int x,y,t; cin >> x >> y >> t; x--; y--;
		G[x].emplace_back(y,t);
		G[y].emplace_back(x,t);
	}
	int v0,a,b,c; cin >> v0 >> a >> b >> c;
	vector<vvl> d(n,vvl(c,vl(2,linf)));
	d[0][v0][0] = 0;
	priority_queue<vl,vector<vl>,greater<vl>> pq;
	pq.push(vl{0,v0,0,0});
	while(!pq.empty()){
		auto x = pq.top(); pq.pop();
		ll cost = x[0], velo = x[1], s = x[2], u = x[3];
		if(d[u][velo][s] < cost) continue;
		for(auto v : G[u]){
			ll nc = cost + v.second * velo;
			ll nv = (velo * a + b) % c;
			ll ns = (s || v.first == n-1);
			if(d[v.first][nv][ns] <= nc) continue;
			d[v.first][nv][ns] = nc;
			pq.emplace(vl{nc,nv,ns,v.first});
		}
	}
	ll ans = linf;
	rep(i,c) chmin(ans, d[0][i][1]);
	cout << ans << "\n";
}
accuracy: 1
time_ms: 120
memory_kb: 18436
final_rank: 10

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <math.h>
#include <map>
using namespace std;
typedef long long int ll;


vector<pair<ll,ll>> g[501];

ll d[501][51][2];

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n,m; cin >> n >> m;
    for(int i=0;i<m;i++){
        int x,y,t; cin >> x >> y >> t;
        x--; y--;
        g[x].push_back({y,t});
        g[y].push_back({x,t});
    }
    int v; cin >> v;
    int a,b,c; cin >> a >> b >> c;
    for(int i=0;i<501;i++){
        for(int j=0;j<51;j++){
            for(int k=0;k<2;k++){
                d[i][j][k]=1e18;
            }
        }
    }
    d[0][v][0]=0;
    priority_queue<pair<pair<ll,int>,pair<int,int>>> pq;
    pq.push(make_pair(make_pair(0,0),make_pair(v,0)));
    while(pq.size()){
        auto p=pq.top(); pq.pop();
        if(-p.first.first!=d[p.first.second][p.second.first][p.second.second])continue;
        //cout << p.first.first << " " << p.first.second << " " << p.second.first << " "  << p.second.second << endl;    
        int s=p.first.second;
        for(auto t:g[s]){
            ll dis=(ll)t.second*(ll)(p.second.first);
            bool flag=p.second.second;
            if(t.first==n-1)flag=true;
            int nv=(a*p.second.first+b)%c;
            if(d[t.first][nv][flag]>-p.first.first+dis){
                d[t.first][nv][flag]=-p.first.first+dis;
                pq.push(make_pair(make_pair(p.first.first-dis,t.first),make_pair(nv,flag)));
            }
        }
    }
    ll res=1e18;
    for(int i=0;i<51;i++){
        res=min(res,d[0][i][1]);
    }
    cout << res << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 9568
final_rank: 2

code_snippet: #pragma GCC target("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
// #include<ext/pb_ds/assoc_container.hpp>
// #include<ext/pb_ds/tree_policy.hpp>
// #include<ext/pb_ds/tag_and_trait.hpp>
// using namespace __gnu_pbds;
// #include<boost/multiprecision/cpp_int.hpp>
// namespace multiprecisioninteger = boost::multiprecision;
// using cint=multiprecisioninteger::cpp_int;
using namespace std;
using ll=long long;
#define double long double
using datas=pair<ll,ll>;
using ddatas=pair<double,double>;
using tdata=pair<ll,datas>;
using vec=vector<ll>;
using mat=vector<vec>;
using pvec=vector<datas>;
using pmat=vector<pvec>;
// using llset=tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;
#define For(i,a,b) for(i=a;i<(ll)b;++i)
#define bFor(i,b,a) for(i=b,--i;i>=(ll)a;--i)
#define rep(i,N) For(i,0,N)
#define rep1(i,N) For(i,1,N)
#define brep(i,N) bFor(i,N,0)
#define brep1(i,N) bFor(i,N,1)
#define all(v) (v).begin(),(v).end()
#define allr(v) (v).rbegin(),(v).rend()
#define vsort(v) sort(all(v))
#define vrsort(v) sort(allr(v))
#define endl "\n"
#define eb emplace_back
#define print(x) cout<<x<<endl
#define printyes print("Yes")
#define printno print("No")
#define printYES print("YES")
#define printNO print("NO")
#define output(v) do{bool f=0;for(auto outi:v){cout<<(f?" ":"")<<outi;f=1;}cout<<endl;}while(0)
#define matoutput(v) do{for(auto outimat:v)output(outimat);}while(0)
const ll mod=1000000007;
// const ll mod=998244353;
const ll inf=1LL<<60;
const double PI=acos(-1);
const double eps=1e-9;
template<class T,class E> ostream& operator<<(ostream& os,pair<T,E>& p){return os<<"{"<<p.first<<","<<p.second<<"}";}
template<class T> inline bool chmax(T& a,T b){bool x=a<b;if(x)a=b;return x;}
template<class T> inline bool chmin(T& a,T b){bool x=a>b;if(x)a=b;return x;}

void startupcpp(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout<<fixed<<setprecision(15);
}

double distance(ddatas x,ddatas y){
  double a=x.first-y.first,b=x.second-y.second;
  return sqrt(a*a+b*b);
}

ll modinv(ll a,ll m=mod) {
  ll b=m,u=1,v=0,t;
  while(b){
    t=a/b;
    a-=t*b; swap(a,b);
    u-=t*v; swap(u,v);
  }
  return (u+m)%m;
}

ll moddevide(ll a,ll b){return (a*modinv(b))%mod;}

vec modncrlistp,modncrlistm;

ll modncr(ll n,ll r){
  if(n<r)return 0;
  ll i,size=modncrlistp.size();
  if(size<=n){
    modncrlistp.resize(n+1);
    modncrlistm.resize(n+1);
    if(!size){
      modncrlistp[0]=modncrlistm[0]=1;
      size++;
    }
    For(i,size,n+1){
      modncrlistp[i]=modncrlistp[i-1]*i%mod;
      modncrlistm[i]=modinv(modncrlistp[i]);
    }
  }
  return modncrlistp[n]*modncrlistm[r]%mod*modncrlistm[n-r]%mod;
}

ll modpow(ll a,ll n,ll m=mod){
  ll res=1;
  while(n>0){
    if(n&1)res=res*a%m;
    a=a*a%m;
    n>>=1;
  }
  return res;
}

ll gcd(ll a,ll b){if(!b)return abs(a);return (a%b==0)?abs(b):gcd(b,a%b);}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}

ll countdigits(ll n){
  ll ans=0;
  while(n){n/=10;ans++;}
  return ans;
}

ll sumdigits(ll n){
  ll ans=0;
  while(n){ans+=n%10;n/=10;}
  return ans;
}
template<class Cap,class Cost> struct mcf_graph{
public:
  mcf_graph(){}
  mcf_graph(int n):_n(n),g(n){}

  int add_edge(int from,int to,Cap cap,Cost cost){
    assert(0<=from&&from<_n);
    assert(0<=to&&to<_n);
    int m=int(pos.size());
    pos.push_back({from,int(g[from].size())});
    int from_id=int(g[from].size());
    int to_id=int(g[to].size())+int(from==to);
    g[from].push_back(_edge{to,to_id,cap,cost});
    g[to].push_back(_edge{from,from_id,0,-cost});
    return m;
  }

  struct edge{
    int from,to;
    Cap cap,flow;
    Cost cost;
  };

  edge get_edge(int i){
    assert(0<=i&&i<int(pos.size()));
    auto _e=g[pos[i].first][pos[i].second];
    auto _re=g[_e.to][_e.rev];
    return edge{
      pos[i].first,_e.to,_e.cap+_re.cap,_re.cap,_e.cost,
    };
  }
  vector<edge> edges(){
    int m=int(pos.size());
    vector<edge> result(m);
    for(int i=0;i<m;++i){
      result[i]=get_edge(i);
    }
    return result;
  }

  pair<Cap,Cost> flow(int s,int t){
    return flow(s,t,numeric_limits<Cap>::max());
  }
  pair<Cap,Cost> flow(int s,int t,Cap flow_limit){
    return slope(s,t,flow_limit).back();
  }
  vector<pair<Cap,Cost>> slope(int s,int t){
    return slope(s,t,numeric_limits<Cap>::max());
  }
  vector<pair<Cap,Cost>> slope(int s,int t,Cap flow_limit){
    assert(0<=s&&s<_n);
    assert(0<=t&&t<_n);
    assert(s!=t);
    // variants(C=maxcost):
    //-(n-1)C<=dual[s]<=dual[i]<=dual[t]=0
    // reduced cost(=e.cost+dual[e.from]-dual[e.to])>=0 for all edge
    vector<Cost> dual(_n,0),dist(_n);
    vector<int> pv(_n),pe(_n);
    vector<bool> vis(_n);
    auto dual_ref=[&](){
      fill(dist.begin(),dist.end(),numeric_limits<Cost>::max());
      fill(pv.begin(),pv.end(),-1);
      fill(pe.begin(),pe.end(),-1);
      fill(vis.begin(),vis.end(),false);
      struct Q{
        Cost key;
        int to;
        bool operator<(Q r)const{ return key>r.key;}
      };
      priority_queue<Q> que;
      dist[s]=0;
      que.push(Q{0,s});
      while(!que.empty()){
        int v=que.top().to;
        que.pop();
        if(vis[v])continue;
        vis[v]=true;
        if(v==t)break;
        // dist[v]=shortest(s,v)+dual[s]-dual[v]
        // dist[v]>=0(all reduced cost are positive)
        // dist[v]<=(n-1)C
        for(int i=0;i<int(g[v].size());++i){
          auto e=g[v][i];
          if(vis[e.to]||!e.cap)continue;
          // |-dual[e.to]+dual[v]|<=(n-1)C
          // cost<=C--(n-1)C+0=nC
          Cost cost=e.cost-dual[e.to]+dual[v];
          if(dist[e.to]-dist[v]>cost){
            dist[e.to]=dist[v]+cost;
            pv[e.to]=v;
            pe[e.to]=i;
            que.push(Q{dist[e.to],e.to});
          }
        }
      }
      if(!vis[t])return false;

      for(int v=0;v<_n;++v){
        if(!vis[v])continue;
        // dual[v]=dual[v]-dist[t]+dist[v]
        //    =dual[v]-(shortest(s,t)+dual[s]-dual[t])+(shortest(s,v)+dual[s]-dual[v])
        //    =-shortest(s,t)+dual[t]+shortest(s,v)
        //    =shortest(s,v)-shortest(s,t)>=0-(n-1)C
        dual[v]-=dist[t]-dist[v];
      }
      return true;
    };
    Cap flow=0;
    Cost cost=0,prev_cost_per_flow=-1;
    vector<pair<Cap,Cost>> result;
    result.push_back({flow,cost});
    while(flow<flow_limit){
      if(!dual_ref())break;
      Cap c=flow_limit-flow;
      for(int v=t;v!=s;v=pv[v]){
        c=min(c,g[pv[v]][pe[v]].cap);
      }
      for(int v=t;v!=s;v=pv[v]){
        auto&e=g[pv[v]][pe[v]];
        e.cap-=c;
        g[v][e.rev].cap+=c;
      }
      Cost d=-dual[s];
      flow+=c;
      cost+=c*d;
      if(prev_cost_per_flow==d){
        result.pop_back();
      }
      result.push_back({flow,cost});
      prev_cost_per_flow=d;
    }
    return result;
  }

private:
  int _n;

  struct _edge{
    int to,rev;
    Cap cap;
    Cost cost;
  };

  vector<pair<int,int>> pos;
  vector<vector<_edge>> g;
};

ll N,M,K,H,W,A,B,C,D;
string s,t;
ll ans;
int main(){
  // startupcpp();
  // int codeforces;cin>>codeforces;while(codeforces--){
  ll i,j;
  cin>>N>>M;
  vec x(M),y(M),t(M);
  rep(i,M){
    cin>>x[i]>>y[i]>>t[i];
    --x[i];--y[i];
  }
  cin>>D>>A>>B>>C;
  vec change(C);
  rep(i,C){
    change[i]=(i*A+B)%C;
  }
  pmat g(N*C+1);
  rep(i,M){
    rep(j,C){
      g[x[i]*C+j].eb(t[i]*j,y[i]*C+change[j]);
      g[y[i]*C+j].eb(t[i]*j,x[i]*C+change[j]);
    }
  }
  vec dist(N*C+1,inf);
  vec sdist(N*C+1,inf);
  priority_queue<datas,pvec,greater<datas>> que;
  que.push(datas(0,D));
  while(!que.empty()){
    auto x=que.top();que.pop();
    if(!chmin(dist[x.second],x.first))continue;
    for(auto next:g[x.second]){
      next.first+=x.first;
      que.push(next);
    }
  }
  rep(j,C){
    que.push(datas(dist[(N-1)*C+j],(N-1)*C+j));
    g[j].eb(0,N*C);
  }
  while(!que.empty()){
    auto x=que.top();que.pop();
    if(!chmin(sdist[x.second],x.first))continue;
    for(auto next:g[x.second]){
      next.first+=x.first;
      que.push(next);
    }
  }
  print(sdist[N*C]);
}
accuracy: 1
time_ms: 50
memory_kb: 18516
final_rank: 9

code_snippet: #include <bits/stdc++.h>
#define inf (long long)(1e17)
using namespace std;

struct dat {
  long long n, v, t;
  dat(long long a = 0, long long b = 0, long long c = 0) : n(a), v(b), t(c) {}
  bool operator<(const dat &r) const {
    if (t != r.t) return t > r.t;
    if (n != r.n) return n < r.n;
    return v < r.v;
  }
};

using P = pair<int, int>;

int n, m, v0, a, b, c;
vector<vector<P>> g;

long long solve();

int main() {
  cin >> n >> m;
  g.resize(n);
  for (int i = 0; i < m; ++i) {
    int x, y, t;
    cin >> x >> y >> t;
    g[--x].emplace_back(--y, t);
    g[y].emplace_back(x, t);
  }
  cin >> v0 >> a >> b >> c;
  cout << solve() << endl;
  return 0;
}

long long solve() {
  auto dijk = [](int st, int go, int v0) {
    vector<vector<long long>> dp(n, vector<long long>(c, inf));
    priority_queue<dat> pq;
    dp[st][v0] = 0;
    pq.push(dat(st, v0, 0));
    while (pq.size()) {
      auto [now, nv, nt] = pq.top();
      pq.pop();
      if (dp[now][nv] != nt) continue;
      for (auto [to, time] : g[now]) {
        dat nxt(to, (a * nv + b) % c, nt + nv * time);
        if (dp[to][nxt.v] > nxt.t) {
          dp[to][nxt.v] = nxt.t;
          pq.push(nxt);
        }
      }
    }
    return dp[go];
  };
  long long res = inf;
  auto zero = dijk(0, n - 1, v0);
  for (int i = 0; i < c; ++i) {
    auto now = dijk(n - 1, 0, i);
    for (int j = 0; j < c; ++j) res = min(res, zero[i] + now[j]);
  }
  return res;
}
accuracy: 1
time_ms: 580
memory_kb: 8876
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define MOD 1000000007
//#define MOD 998244353
#define INF 1145141919810893364
//#define INF 810114514
#define PI 3.141592653589
typedef long long ll;
typedef pair<ll,ll> PP;
//#define int ll
#define setdouble setprecision
#define REP(i,n) for(int i=0;i<(n);++i)
#define OREP(i,n) for(int i=1;i<=(n);++i)
#define RREP(i,n) for(int i=(n)-1;i>=0;--i)
#define GOODBYE do { cout << "0" << endl; return 0; } while (false)
#define MM <<" "<<
#define Endl endl
#define debug false
#define debug2 false

class Dijkstra{
    /*
    Copyright (c) 2020 0214sh7
    https://github.com/0214sh7/library/
    */
    private:
    typedef std::pair<long long,int> P;
    std::vector<std::vector<P>> G;
    int V;
    std::priority_queue<P,std::vector<P>,std::greater<P>> que;
    
    public:
    void init(std::vector<std::pair<std::pair<int,int>,long long>> edge){
        //頂点数を決定する
        V=0;
        for(int i=0;i<edge.size();i++){
            V=std::max(V,edge[i].first.first+1);
            V=std::max(V,edge[i].first.second+1);
        }
        
        //辺集合を扱いやすい形式に変換する
        G.resize(V);
        for(int i=0;i<edge.size();i++){
            int from=edge[i].first.first,to=edge[i].first.second;
            long long cost=edge[i].second;
            G[from].push_back({cost,to});
        }
    }
    
    std::vector<long long> solve(int s){
        std::vector<long long> d;
        //INFで初期化する
        for(int i=0;i<V;i++){
            d.push_back(INF);
        }
        d[s]=0;
        que.push({0,s});
        //queは{cost,to}をコストが小さい順に出す
        while(!que.empty()){
            P p = que.top();
            que.pop();
            int v=p.second;
            if(d[v]<p.first)continue;
            for(int i=0;i<G[v].size();i++){
                P e = G[v][i];
                if(d[e.second]>d[v]+e.first){
                    d[e.second] = d[v]+e.first;
                    que.push({d[e.second],e.second});
                }
            }
        }
        return d;
    }
    
    //init:{ {int,int},longlong}のvectorを渡すことで有向グラフを構築する
    //solve:始点を渡すとinitで構築したグラフでダイクストラをし、コストのvectorを返す
};


signed main(void){
    
    int N,M;
    long long x;
    vector<int> X,Y;
    vector<long long>T;
    int v0,A,B,C;
    
    cin >> N >> M;
    REP(i,M){
        cin >> x;x--;X.push_back(x);
        cin >> x;x--;Y.push_back(x);
        cin >> x;T.push_back(x);
    }
    cin >> v0 >> A >> B >> C;
    
    //行きの処理上の頂点番号 = 実際の頂点番号*50 + 速度
    //帰りの処理上の頂点番号 = (N+実際の頂点番号)*50 + 速度
    
    std::vector<std::pair<std::pair<int,int>,long long>> edge;
    std::pair<std::pair<int,int>,long long> h;
    
    //行き
    REP(i,M){
        REP(v,C){
            h.first.first = X[i]*50 + v;
            h.first.second = Y[i]*50 + (A*v+B)%C;
            h.second = T[i]*v;
            edge.push_back(h);
            
            h.first.first = Y[i]*50 + v;
            h.first.second = X[i]*50 + (A*v+B)%C;
            h.second = T[i]*v;
            edge.push_back(h);
        }
    }
    //帰り
    REP(i,M){
        REP(v,C){
            h.first.first = (N+X[i])*50 + v;
            h.first.second = (N+Y[i])*50 + (A*v+B)%C;
            h.second = T[i]*v;
            edge.push_back(h);
            
            h.first.first = (N+Y[i])*50 + v;
            h.first.second = (N+X[i])*50 + (A*v+B)%C;
            h.second = T[i]*v;
            edge.push_back(h);
        }
    }
    //行きのNと帰りのNを連結しておく
    REP(v,C){
        h.first.first = (N-1)*50 + v;
        h.first.second = (N+N-1)*50 + v;
        h.second = 0;
        edge.push_back(h);
    }
    
    Dijkstra dijkstra;
    dijkstra.init(edge);
    
    vector<long long> D = dijkstra.solve(0*50+v0);
    
    
    long long Ans=INF;
    REP(v,C){
        Ans = min(Ans,D[(N+0)*50+v]);
    }
    cout << Ans << endl;
    
    #if debug
    int s[9]={3,8,1,0,5,7,6,2,4};
    REP(i,C){
        REP(j,N){
            cout << D[(0+j)*50+s[i]] << " ";
        }cout << "   ";
        RREP(j,N){
            cout << D[(N+j)*50+s[i]] << " ";
        }cout << endl;
        
    }cout << endl;
    #endif
    
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 54800
final_rank: 17

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

int main() {
  int N,M;
  cin>>N>>M;
  vector<vector<pair<int,int64_t>>> G(N*2-1);
  for(int i=0;i<M;i++){
    int a,b,c;
    cin>>a>>b>>c;
    a--,b--;
    G.at(a).push_back(make_pair(b,c));
    G.at(b).push_back(make_pair(a,c));
    G.at((2*N-2)-a).push_back(make_pair((2*N-2)-b,c));
    G.at((2*N-2)-b).push_back(make_pair((2*N-2)-a,c));
  }
  int v,a,b,c;
  cin>>v>>a>>b>>c;
  vector<int> p(c);
  for(int i=0;i<c;i++){
    p.at(i)=(a*i+b)%c;
  }
  vector<int64_t> r((2*N-1)*c,1000000000000000000);
  priority_queue<pair<int64_t,int>,vector<pair<int64_t,int>>,greater<pair<int64_t,int>>> pq;
  pq.push(make_pair(0,v));
  r.at(v)=0;
  while(!pq.empty()){
    int64_t x,y;
    tie(x,y)=pq.top();
    pq.pop();
    int64_t k=y/c,l=y%c;
    if(r.at(y)<x){
      continue;
    }
    else if(k==2*N-2){
      cout<<x<<endl;
      break;
    }
    else{
      for(auto Q:G.at(k)){
        if(r.at(Q.first*c+p.at(l))>x+l*Q.second){
          r.at(Q.first*c+p.at(l))=x+l*Q.second;
          pq.push(make_pair(x+l*Q.second,Q.first*c+p.at(l)));
        }
      }
    }
  }
    
}
accuracy: 1
time_ms: 10
memory_kb: 7532
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
using uint = unsigned;
using pcc = pair<char, char>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pdd = pair<double, double>;
using tuplis = array<ll, 3>;
template<class T> using pq = priority_queue<T, vector<T>, greater<T>>;
const ll LINF=0x1fffffffffffffff;
const ll MINF=0x7fffffffffff;
const int INF=0x3fffffff;
const int MOD=1000000007;
const int MODD=998244353;
const ld DINF=numeric_limits<ld>::infinity();
const ld EPS=1e-9;
const ld PI=3.1415926535897932;
const ll dx[] = {0, 1, 0, -1, 1, -1, 1, -1};
const ll dy[] = {1, 0, -1, 0, 1, 1, -1, -1};
#define overload4(_1,_2,_3,_4,name,...) name
#define overload3(_1,_2,_3,name,...) name
#define rep1(n) for(ll i=0;i<n;++i)
#define rep2(i,n) for(ll i=0;i<n;++i)
#define rep3(i,a,b) for(ll i=a;i<b;++i)
#define rep4(i,a,b,c) for(ll i=a;i<b;i+=c)
#define rep(...) overload4(__VA_ARGS__,rep4,rep3,rep2,rep1)(__VA_ARGS__)
#define rrep1(n) for(ll i=(n);i--;)
#define rrep2(i,n) for(ll i=(n);i--;)
#define rrep3(i,a,b) for(ll i=(b);i-->(a);)
#define rrep4(i,a,b,c) for(ll i=a+(b-a-1)/c*c;i>=a;i-=c)
#define rrep(...) overload4(__VA_ARGS__,rrep4,rrep3,rrep2,rrep1)(__VA_ARGS__)
#define each(i,a) for(auto&& i:a)
#define all1(i) begin(i),end(i)
#define all2(i,a) begin(i),begin(i)+a
#define all3(i,a,b) begin(i)+a,begin(i)+b
#define all(...) overload3(__VA_ARGS__,all3,all2,all1)(__VA_ARGS__)
#define rall1(i) (i).rbegin(),(i).rend()
#define rall2(i,k) (i).rbegin(),(i).rbegin()+k
#define rall3(i,a,b) (i).rbegin()+a,(i).rbegin()+b
#define rall(...) overload3(__VA_ARGS__,rall3,rall2,rall1)(__VA_ARGS__)
#define sum(...) accumulate(all(__VA_ARGS__),0LL)
#define dsum(...) accumulate(all(__VA_ARGS__),0.0L)
#define elif else if
#define unless(a) if(!(a))
#define mp make_pair
#define mt make_tuple
#define INT(...) int __VA_ARGS__;in(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__;in(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__;in(__VA_ARGS__)
#define STR(...) string __VA_ARGS__;in(__VA_ARGS__)
#define CHR(...) char __VA_ARGS__;in(__VA_ARGS__)
#define DBL(...) double __VA_ARGS__;in(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__;in(__VA_ARGS__)
#define Sort(a) sort(all(a))
#define Rev(a) reverse(all(a))
#define Uniq(a) sort(all(a));a.erase(unique(all(a)),end(a))
#define vec(type,name,...) vector<type> name(__VA_ARGS__)
#define VEC(type,name,size) vector<type> name(size);in(name)
#define vv(type,name,h,...) vector<vector<type>>name(h,vector<type>(__VA_ARGS__))
#define VV(type,name,h,w) vector<vector<type>>name(h,vector<type>(w));in(name)
#define vvv(type,name,h,w,...) vector<vector<vector<type>>>name(h,vector<vector<type>>(w,vector<type>(__VA_ARGS__)))
template<class T> auto min(const T& a){ return *min_element(all(a)); }
template<class T> auto max(const T& a){ return *max_element(all(a)); }
inline ll popcnt(ull a){ return __builtin_popcountll(a); }
ll gcd(ll a, ll b){ while(b){ ll c = b; b = a % b; a = c; } return a; }
ll lcm(ll a, ll b){ if(!a || !b) return 0; return a * b / gcd(a, b); }
ll intpow(ll a, ll b){ ll ans = 1; while(b){ if(b & 1) ans *= a; a *= a; b /= 2; } return ans; }
ll modpow(ll a, ll b, ll p){ ll ans = 1; while(b){ if(b & 1) (ans *= a) %= p; (a *= a) %= p; b /= 2; } return ans; }
template<class T, class U> bool chmin(T& a, const U& b){ if(a > b){ a = b; return 1; } return 0; }
template<class T, class U> bool chmax(T& a, const U& b){ if(a < b){ a = b; return 1; } return 0; }
vector<ll> iota(ll n){ vector<ll> a(n); iota(a.begin(), a.end(), 0); return a; }
vector<pll> factor(ull x){ vector<pll> ans; for(ll i = 2; i * i <= x; i++) if(x % i == 0){ ans.push_back({i, 1}); while((x /= i) % i == 0) ans.back().second++; } if(x != 1) ans.push_back({x, 1}); return ans; }
map<ll,ll> factor_map(ull x){ map<ll,ll> ans; for(ll i = 2; i * i <= x; i++) if(x % i == 0){ ans[i] = 1; while((x /= i) % i == 0) ans[i]++; } if(x != 1) ans[x] = 1; return ans; }
vector<uint> divisor(uint x){ vector<uint> ans; for(uint i = 1; i * i <= x; i++) if(x % i == 0) ans.push_back(i); rrep(ans.size() - (ans.back() * ans.back() == x)) ans.push_back(x / ans[i]); return ans; }
template<class T> unordered_map<T, ll> press(vector<T>& a){ auto b = a; sort(all(b)); b.erase(unique(all(b)), b.end()); unordered_map<T, ll> ans; rep(b.size()) ans[b[i]] = i; each(i, a) i = ans[i]; return ans; }
template<class T> map<T, ll> press_map(vector<T>& a){ auto b = a; sort(all(b)); b.erase(unique(all(b)), b.end()); map<T, ll> ans; rep(b.size()) ans[b[i]] = i; each(i, a) i = ans[i]; return ans; }
int scan(){ return getchar(); }
void scan(int& a){ scanf("%d", &a); }
void scan(unsigned& a){ scanf("%u", &a); }
void scan(long& a){ scanf("%ld", &a); }
void scan(long long& a){ scanf("%lld", &a); }
void scan(unsigned long long& a){ scanf("%llu", &a); }
void scan(char& a){ do{ a = getchar(); }while(a == ' ' || a == '\n'); }
void scan(float& a){ scanf("%f", &a); }
void scan(double& a){ scanf("%lf", &a); }
void scan(long double& a){ scanf("%Lf", &a); }
void scan(vector<bool>& a){ for(unsigned i = 0; i < a.size(); i++){ int b; scan(b); a[i] = b; } }
void scan(char a[]){ scanf("%s", a); }
void scan(string& a){ cin >> a; }
template<class T> void scan(vector<T>&);
template<class T, size_t size> void scan(array<T, size>&);
template<class T, class L> void scan(pair<T, L>&);
template<class T, size_t size> void scan(T(&)[size]);
template<class T> void scan(vector<T>& a){ for(auto&& i : a) scan(i); }
template<class T> void scan(deque<T>& a){ for(auto&& i : a) scan(i); }
template<class T, size_t size> void scan(array<T, size>& a){ for(auto&& i : a) scan(i); }
template<class T, class L> void scan(pair<T, L>& p){ scan(p.first); scan(p.second); }
template<class T, size_t size> void scan(T (&a)[size]){ for(auto&& i : a) scan(i); }
template<class T> void scan(T& a){ cin >> a; }
void in(){}
template <class Head, class... Tail> void in(Head& head, Tail&... tail){ scan(head); in(tail...); }
void print(){ putchar(' '); }
void print(bool a){ printf("%d", a); }
void print(int a){ printf("%d", a); }
void print(unsigned a){ printf("%u", a); }
void print(long a){ printf("%ld", a); }
void print(long long a){ printf("%lld", a); }
void print(unsigned long long a){ printf("%llu", a); }
void print(char a){ printf("%c", a); }
void print(char a[]){ printf("%s", a); }
void print(const char a[]){ printf("%s", a); }
void print(float a){ printf("%.15f", a); }
void print(double a){ printf("%.15f", a); }
void print(long double a){ printf("%.15Lf", a); }
void print(const string& a){ for(auto&& i : a) print(i); }
template<class T> void print(const vector<T>&);
template<class T, size_t size> void print(const array<T, size>&);
template<class T, class L> void print(const pair<T, L>& p);
template<class T, size_t size> void print(const T (&)[size]);
template<class T> void print(const vector<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ putchar(' '); print(*i); } }
template<class T> void print(const deque<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ putchar(' '); print(*i); } }
template<class T, size_t size> void print(const array<T, size>& a){ print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ putchar(' '); print(*i); } }
template<class T, class L> void print(const pair<T, L>& p){ print(p.first); putchar(' '); print(p.second); }
template<class T, size_t size> void print(const T (&a)[size]){ print(a[0]); for(auto i = a; ++i != end(a); ){ putchar(' '); print(*i); } }
template<class T> void print(const T& a){ cout << a; }
int out(){ putchar('\n'); return 0; }
template<class T> int out(const T& t){ print(t); putchar('\n'); return 0; }
template<class Head, class... Tail> int out(const Head& head, const Tail&... tail){ print(head); putchar(' '); out(tail...); return 0; }
#ifdef DEBUG
inline ll __lg(ull __n){ return sizeof(ull) * __CHAR_BIT__  - 1 - __builtin_clzll(__n); }
#define debug(...) { print(#__VA_ARGS__); print(":"); out(__VA_ARGS__); }
#else
#define debug(...) void(0)
#endif
int first(bool i = true){ return out(i?"first":"second"); }
int yes(bool i = true){ return out(i?"yes":"no"); }
int Yes(bool i = true){ return out(i?"Yes":"No"); }
int No(){ return out("No"); }
int YES(bool i = true){ return out(i?"YES":"NO"); }
int NO(){ return out("NO"); }
int Yay(bool i = true){ return out(i?"Yay!":":("); }
int possible(bool i = true){ return out(i?"possible":"impossible"); }
int Possible(bool i = true){ return out(i?"Possible":"Impossible"); }
int POSSIBLE(bool i = true){ return out(i?"POSSIBLE":"IMPOSSIBLE"); }
void Case(ll i){ printf("Case #%lld: ", i); }



struct WeightedEdge{
    ll to, cost;
    WeightedEdge(){}
    WeightedEdge(ll to, ll cost): to(to), cost(cost){}
    operator ll() const { return to; }
};
struct WeightedGraph{
    using E = WeightedEdge;
    vector<vector<E>> g;
    WeightedGraph(){}
    WeightedGraph(ll n): g(n){}
    vector<E>& operator[](ll at){ return g[at]; }
    operator vector<vector<E>>&(){ return g; }
    auto begin() const { return g.cbegin(); }
    auto end() const { return g.cend(); }
    ll size() const { return g.size(); }
    void resize(ll n){ g.resize(n); }
    const vector<E>& operator[](ll at) const { return g[at]; }
    operator const vector<vector<E>>&() const { return g; }
    void add_edge(ll a, ll b, ll cost){
        g[a].emplace_back(b, cost);
        g[b].emplace_back(a, cost);
    }
    void add_directed_edge(ll from, ll to, ll cost){
        g[from].emplace_back(to, cost);
    }
    template<ll start_index = 1, bool directed = false> void input_graph(ll m){
        while(m--){
            ll a, b, c;
            scanf("%lld%lld%lld", &a, &b, &c);
            a -= start_index;
            b -= start_index;
            g[a].emplace_back(b, c);
            if(!directed) g[b].emplace_back(a, c);
        }
    }
    template<ll start_index = 1> void input_tree(ll n){ input_graph<start_index>(n - 1); }
};
ll n, a, b, c, v;
template<class Graph> ll Dijkstra(const Graph& g){
    using tuplis=array<ll,4>;
    ll cost[500][50][2];
    bool used[500][50][2]={};
    memset(cost, 0x33, sizeof(cost));
    pq<tuplis> q;
    cost[0][v][0] = 0;
    q.push({0, 0, v, 0});
    while(q.size()){
        ll at=q.top()[1],v=q.top()[2],f=q.top()[3];
        q.pop();
        if(used[at][v][f])continue;
        used[at][v][f] = 1;
        each(at2, g[at]){
            ll v2=(v*a+b)%c;
            ll f2=f||at2==n-1;
            if(chmin(cost[at2][v2][f2],cost[at][v][f]+at2.cost*v))q.push({cost[at2][v2][f2],at2,v2,f2});
        }
    }
    ll ans=LINF;
    rep(50)chmin(ans,cost[0][i][1]);
    return ans;
}
signed main(){
    in(n);
    LL(m);
    WeightedGraph g(n);
    g.input_graph(m);
    in(v,a,b,c);
    out(Dijkstra(g));
}
accuracy: 1
time_ms: 50
memory_kb: 11844
final_rank: 8

code_snippet: #include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cstdint>
#include <cstdlib>
#include <cmath>
#include <complex>
#include <chrono>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
#include <random>
#include <utility>
#include <limits>
#include <list>

/* template start */
 
#define rep(i, a, b) for (long long i = (a); (i) < (b); (i)++)
#define all(i) i.begin(), i.end()

#ifdef LOCAL
#define debug(...) std::cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif

void debug_out(){std::cerr<<std::endl;}

template<typename Head,typename... Tail>
void debug_out(Head h,Tail... t){
  std::cerr<<" "<<h;
  if(sizeof...(t)>0)std::cout<<" :";
  debug_out(t...);
}
 
template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, std::pair<T1, T2> pa) {
  return os << pa.first << " " << pa.second;
}
 
template <typename T>
std::ostream& operator<<(std::ostream& os, std::vector<T> vec) {
  for (std::size_t i = 0; i < vec.size(); i++)os << vec[i] << (i + 1 == vec.size() ? "" : " ");
  return os;
}
 
template<typename T1,typename T2>
inline bool chmax(T1& a,T2 b){return a<b && (a=b,true);}
 
template<typename T1,typename T2>
inline bool chmin(T1& a,T2 b){return a>b && (a=b,true);}

template<typename Num>
constexpr Num mypow(Num a, long long b) {
  if(b==0)return 1;
  if (a==0)return 0;
  Num x = 1;
  while (b > 0) {
    if(b & 1)x*=a;
    a*=a;
    b >>= 1;
  }
  return x;
}

template <std::uint_fast64_t Modulus> class modint {
  using u64 = std::uint_fast64_t;

public:
  u64 a;

  constexpr modint(const u64 x = 0) noexcept : a(x % Modulus) {}
  constexpr u64 &value() noexcept { return a; }
  constexpr const u64 &value() const noexcept { return a; }
  constexpr bool operator==(const modint rhs) const noexcept {return a==rhs.a;}
  constexpr bool operator!=(const modint rhs) const noexcept {return !(*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) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= Modulus) {
      a -= Modulus;
    }
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a) {
      a += Modulus;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % Modulus;
    return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
    u64 exp = Modulus - 2;
    while (exp) {
      if (exp % 2) {
        *this *= rhs;
      }
      rhs *= rhs;
      exp /= 2;
    }
    return *this;
  }
};

/* template end */

using ll = long long;

struct Edge{
  int x,y;
  ll cost;
  Edge(int a,int b,ll c):x(a),y(b),cost(c){}
};

using P=std::pair<int,ll>;

signed main() {
  std::cin.tie(nullptr);
  std::ios::sync_with_stdio(false);

  ll n,m;
  std::cin>>n>>m;

  std::vector<Edge> edges;
  rep(i,0,m){
    ll x,y,t;
    std::cin>>x>>y>>t;
    x--;y--;
    if(x>y)std::swap(x,y);
    edges.emplace_back(x,y,t);
  }

  const ll SIZE=2*n-1;
  constexpr ll TIME=50;

  std::vector<std::vector<P>> graph(TIME*SIZE);

  ll v;
  std::cin>>v;
  ll start=v;
  ll a,b,c;
  std::cin>>a>>b>>c;

  rep(i,0,TIME+1){
    ll nv=(a*v+b)%c;
    for(const auto& e:edges){
      graph[v*SIZE+e.x].emplace_back(nv*SIZE+e.y,v*e.cost);
      graph[v*SIZE+e.y].emplace_back(nv*SIZE+e.x,v*e.cost);
      graph[v*SIZE+2*n-2-e.x].emplace_back(nv*SIZE+2*n-2-e.y,v*e.cost);
      graph[v*SIZE+2*n-2-e.y].emplace_back(nv*SIZE+2*n-2-e.x,v*e.cost);
    }
    v=nv;
  }

  constexpr ll INF=1e18;

  std::vector<ll> d(TIME*SIZE,INF);
  using PA=std::pair<long long,int>;
  std::priority_queue<PA,std::vector<PA>,std::greater<PA>> que;
  d[start*SIZE]=0;

  que.emplace(0,start*SIZE);

  while(!que.empty()){
    PA p=que.top();
    que.pop();
    int va=p.second;
    if(d[va]<p.first)continue;
    for(const auto& e:graph[va]){
      if(d[e.first] > d[va]+e.second){
        d[e.first]=d[va]+e.second;
        que.emplace(d[e.first],e.first);
      }
    }
  }

  ll ans=INF;

  rep(i,0,TIME){
    chmin(ans,d[i*SIZE+2*n-2]);
  }

  std::cout<<ans<<"\n";

  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 30316
final_rank: 13

code_snippet: #include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cstdint>
#include <cstdlib>
#include <cmath>
#include <complex>
#include <chrono>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
#include <random>
#include <utility>
#include <limits>
#include <list>

/* template start */
 
#define rep(i, a, b) for (long long i = (a); (i) < (b); (i)++)
#define all(i) i.begin(), i.end()

#ifdef LOCAL
#define debug(...) std::cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif

void debug_out(){std::cerr<<std::endl;}

template<typename Head,typename... Tail>
void debug_out(Head h,Tail... t){
  std::cerr<<" "<<h;
  if(sizeof...(t)>0)std::cout<<" :";
  debug_out(t...);
}
 
template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, std::pair<T1, T2> pa) {
  return os << pa.first << " " << pa.second;
}
 
template <typename T>
std::ostream& operator<<(std::ostream& os, std::vector<T> vec) {
  for (std::size_t i = 0; i < vec.size(); i++)os << vec[i] << (i + 1 == vec.size() ? "" : " ");
  return os;
}
 
template<typename T1,typename T2>
inline bool chmax(T1& a,T2 b){return a<b && (a=b,true);}
 
template<typename T1,typename T2>
inline bool chmin(T1& a,T2 b){return a>b && (a=b,true);}

template<typename Num>
constexpr Num mypow(Num a, long long b) {
  if(b==0)return 1;
  if (a==0)return 0;
  Num x = 1;
  while (b > 0) {
    if(b & 1)x*=a;
    a*=a;
    b >>= 1;
  }
  return x;
}

template <std::uint_fast64_t Modulus> class modint {
  using u64 = std::uint_fast64_t;

public:
  u64 a;

  constexpr modint(const u64 x = 0) noexcept : a(x % Modulus) {}
  constexpr u64 &value() noexcept { return a; }
  constexpr const u64 &value() const noexcept { return a; }
  constexpr bool operator==(const modint rhs) const noexcept {return a==rhs.a;}
  constexpr bool operator!=(const modint rhs) const noexcept {return !(*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) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= Modulus) {
      a -= Modulus;
    }
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a) {
      a += Modulus;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % Modulus;
    return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
    u64 exp = Modulus - 2;
    while (exp) {
      if (exp % 2) {
        *this *= rhs;
      }
      rhs *= rhs;
      exp /= 2;
    }
    return *this;
  }
};

/* template end */

using ll = long long;

struct Edge{
  int x,y;
  ll cost;
  Edge(int a,int b,ll c):x(a),y(b),cost(c){}
};

using P=std::pair<int,ll>;

int main() {
  std::cin.tie(nullptr);
  std::ios::sync_with_stdio(false);

  ll n,m;
  std::cin>>n>>m;

  std::vector<Edge> edges;
  rep(i,0,m){
    ll x,y,t;
    std::cin>>x>>y>>t;
    x--;y--;
    if(x>y)std::swap(x,y);
    edges.emplace_back(x,y,t);
  }

  const ll SIZE=2*n-1;
  constexpr ll TIME=51;

  std::vector<std::vector<P>> graph(TIME*SIZE);

  ll v;
  std::cin>>v;
  ll a,b,c;
  std::cin>>a>>b>>c;

  rep(i,0,TIME-1){
    for(const auto& e:edges){
      graph[i*SIZE+e.x].emplace_back((i+1)*SIZE+e.y,v*e.cost);
      graph[i*SIZE+e.y].emplace_back((i+1)*SIZE+e.x,v*e.cost);
      graph[i*SIZE+2*n-2-e.x].emplace_back((i+1)*SIZE+2*n-2-e.y,v*e.cost);
      graph[i*SIZE+2*n-2-e.y].emplace_back((i+1)*SIZE+2*n-2-e.x,v*e.cost);
    }
    v=(a*v+b)%c;
  }

  constexpr ll INF=1e18;

  std::vector<ll> d(TIME*SIZE,INF);
  using PA=std::pair<long long,int>;
  std::priority_queue<PA,std::vector<PA>,std::greater<PA>> que;
  d[0]=0;

  que.emplace(0,0);

  while(!que.empty()){
    PA p=que.top();
    que.pop();
    int va=p.second;
    if(d[va]<p.first)continue;
    for(const auto& e:graph[va]){
      if(d[e.first] > d[va]+e.second){
        d[e.first]=d[va]+e.second;
        que.emplace(d[e.first],e.first);
      }
    }
  }

  ll ans=INF;

  rep(i,0,TIME){
    chmin(ans,d[i*SIZE+2*n-2]);
  }

  std::cout<<ans<<"\n";

  return 0;
}
accuracy: 0.9655172413793104
time_ms: 40
memory_kb: 30180
final_rank: 19

code_snippet: #include <iostream>
#include <algorithm>
#include <utility>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <map>
#include <math.h>
#include <string.h>
#include <iomanip>
#include <numeric>
#include <cstdlib>
#include <cstdint>
#include <cmath>
#include <functional>
#include <limits>
#include <cassert>
#include <bitset>

using namespace std;

/* template */

using ll = long long;

void debug_out() { std::cout << std::endl; }
 
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cout << H << " ";
  debug_out(T...);
}

#ifdef LOCAL
#define debug(...) cout << "debug: "; debug_out(__VA_ARGS__)
#else
#define debug(...) 
#endif

#define rep(i, a, n) for (int i = (int)(a); i < (int)(n); i++)
#define rrep(i, a, n) for (int i = ((int)(n-1)); i >= (int)(a); i--)
#define Rep(i, a, n) for (long long i = (long long)(a); i< (long long)(n); i++)
#define RRep(i, a, n) for (long long i = ((long long)(n-1ll)); i>=(long long)(a); i--)
#define all(v) (v).begin(),(v).end()
#define rall(v) (v).rbegin(),(v).rend()

/* xxpoxx's definition */
#define FOR(i, a, b) for (ll i = (a); i < (b); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) (a).begin(), (a).end()
using vl = vector<ll>;
string abc = "abcdefghijklmnopqrstuvwxyz";
string ABC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

template <typename T>
std::ostream& operator<<(std::ostream& os, std::vector<T> vec) {
  for (std::size_t i = 0; i < vec.size(); i++)os << vec[i] << (i + 1 == vec.size() ? "" : " ");
  return os;
}

struct Edge{
    int to;
    ll weight;
    Edge(int t, ll w) : to(t), weight(w){ }
};

struct edge{
    int from;
    int to;
    ll weight;
    edge(int f,int t,ll w) : from(f), to(t), weight(w){ }
};


using Graph = vector<vector<Edge>>;
using graph = vector<vector<int>>;
using edges = vector<edge>;

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

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

template <class T>
T lcm(T a, T b){
    return (a*b)/gcd(a,b);
}

constexpr ll LNF = 1LL<<60;

constexpr int INF = 1e9+7;

const double PI=3.14159265358979323846;


vector<int> dx = {-1,0,1,0,-1,1,-1,1};
vector<int> dy = {0,-1,0,1,1,-1,-1,1};

/* template */

vector<ll> dijkstra(int s,int n,Graph g){
    typedef pair<ll,ll> P;
    vector<ll> d(n,LNF);
    priority_queue<P,vector<P>,greater<P>> que;
    d[s] = 0;
    que.push(P(0,s));
    while(!que.empty()){
        P p = que.top();
        que.pop();
        int v = p.second;
        if(d[v]<p.first) continue;
        rep(i,0,g[v].size()){
            Edge e = g[v][i];
            if(d[e.to]>d[v]+e.weight){
                d[e.to] = d[v] + e.weight;
                que.push(P(d[e.to],e.to));
            }
        }
    }
    return d;
}

int main(){

    int n,m; cin >> n >> m;
    vector<vector<ll>> p(m,vector<ll>(3));
    rep(i,0,m){
        cin >> p[i][0] >> p[i][1] >> p[i][2];
        p[i][0]--;
        p[i][1]--;
    }
    int v0; cin >> v0;
    int a,b,c; cin >> a >> b >> c;
    Graph g(n*c);
    rep(i,0,m){
        int x = p[i][0];
        int y = p[i][1];
        ll t = p[i][2];
        rep(v,0,c){
            g[x*c+v].emplace_back(Edge(y*c+(a*v+b)%c,v*t));
            g[y*c+v].emplace_back(Edge(x*c+(a*v+b)%c,v*t));
        }
    }
    vector<ll> d = dijkstra(v0,n*c,g);
    ll ans = LNF;
    rep(i,0,c){
        vector<ll> e = dijkstra((n-1)*c+i,n*c,g);
        rep(j,0,c){
            chmin(ans,d[(n-1)*c+i]+e[j]);
        }
    }
    cout << ans << endl;
    /*
    ll N,S,P,C;
    cin >>N;
    vector<ll> r(N),score(N),Sr(N),Pr(N),Cr(N);
    for(ll i=0;i<N;i++) cin >>r[i];
    vector<pair<ll,ll>> s(N), p(N), c(N);
    for(ll i=0;i<N;i++){
        ll a1,a2,a3;
        cin >>a1>>a2>>a3;
        s[i]=make_pair(a1,i);
        p[i]=make_pair(a2,i);
        c[i]=make_pair(a3,i);
    }
    S=s[0].first; P=p[0].first; C=c[0].first;
    sort(s.begin(),s.end());
    sort(p.begin(),p.end());
    sort(c.begin(),c.end());
    reverse(s.begin(),s.end());
    reverse(p.begin(),p.end());
    reverse(c.begin(),c.end());
    //スマイルの初期点計算
    ll douritsu=0;
    ll rank=0;
    for(ll i=0;i<N;i++){
        score[s[i].second]+=r[rank];
        Sr[s[i].second]=rank;
        if(i!=N-1){
            if(s[i].first==s[i+1].first) douritsu++;
            else{
                rank+=douritsu+1;
                douritsu=0;
            }
        }
    }
    //ぴゅあの初期点計算
    douritsu=0;
    rank=0;
    for(ll i=0;i<N;i++){
        score[p[i].second]+=r[rank];
        Pr[p[i].second]=rank;
        if(i!=N-1){
            if(p[i].first==p[i+1].first) {
                douritsu++;
            }else{
                rank+=douritsu+1;
                douritsu=0;
            }
        }
    }
    //くーるの初期点計算
    douritsu=0;
    rank=0;
    for(ll i=0;i<N;i++){
        score[c[i].second]+=r[rank];
        Cr[c[i].second]=rank;
        if(i!=N-1){
            if(c[i].first==c[i+1].first) {
                douritsu++;
            }else{
                rank+=douritsu+1;
                douritsu=0;
            }
        }
    }
    vector<ll> score2 = score;
    ll ans=LNF;
    //for(ll j=1; j<N; j++) cout << score[j] << endl;
    // すまいるを値変えるとき
    for(ll i=S+1;i<=100;i++){
        for(ll j=0;j<N;j++){
            if(s[j].second==0) continue;
            if(s[j].first>i) continue;
            else if(s[j].first==i) score2[0]+=r[j]-r[Sr[0]];
            else if(s[j].first>=s[0].first) score2[j]+=r[Sr[j]]-r[Sr[j]+1];
        }
        ll rank=N;
        for(ll j=1; j<N; j++) {
            if(score2[j]<=score2[0]) rank--;
        }
        cout << i << " " << rank << endl;
        if(rank<=8) ans=min(ans,i-S);
    }
    cout << ans;
    */
}
accuracy: 1
time_ms: 630
memory_kb: 25720
final_rank: 18

code_snippet: #include <algorithm>
#include <cstddef>
#include <cstdint>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <string>
#include <vector>

using usize = std::size_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;

template <class T> void chmin(T &a, const T &b) {
  if (b < a)
    a = b;
}

struct edge {
  usize to;
  u64 cost;

  bool operator<(const edge &r) const { return r.cost < cost; }
};

static constexpr u64 inf = std::numeric_limits<u64>::max();

std::vector<u64> dijkstra(const std::vector<std::vector<edge>> &g,
                          const usize s) {
  const usize n = g.size();
  std::vector<u64> dist(n, inf);

  dist[s] = 0;
  std::priority_queue<edge> que;
  que.push({s, 0});

  while (!que.empty()) {
    const usize v = que.top().to;
    const usize c = que.top().cost;
    que.pop();
    if (dist[v] < c) {
      continue;
    }
    for (const auto &e : g[v]) {
      if (dist[e.to] > c + e.cost) {
        dist[e.to] = c + e.cost;
        que.push({e.to, dist[e.to]});
      }
    }
  }

  return dist;
}

int main() {

  usize n, m;
  std::cin >> n >> m;

  struct e_tp {
    usize x, y;
    u64 t;
  };

  std::vector<e_tp> es(m);
  for (auto &e : es) {
    std::cin >> e.x >> e.y >> e.t;
    e.x -= 1;
    e.y -= 1;
  }

  usize v0;
  std::cin >> v0;

  usize a, b, c;
  std::cin >> a >> b >> c;

  const auto idx = [&](const usize r, const usize ve, const usize i) {
    return (r * c + ve) * n + i;
  };

  std::vector<std::vector<edge>> g(2 * c * n);

  const auto span = [&](const usize x, const usize y, const u64 t) {
    for (const auto r : {0, 1}) {
      for (usize i = 0; i != c; ++i) {
        g[idx(r, i, x)].push_back({idx(r, (a * i + b) % c, y), t * i});
      }
    }
  };

  for (const auto &e : es) {
    span(e.x, e.y, e.t);
    span(e.y, e.x, e.t);
  }

  for (usize i = 0; i != c; ++i) {
    g[idx(0, i, n - 1)].push_back({idx(1, i, n - 1), 0});
  }

  u64 ans = inf;
  const auto dist = dijkstra(g, idx(0, v0, 0));

  for (usize i = 0; i != c; ++i) {
    chmin(ans, dist[idx(1, i, 0)]);
  }

  std::cout << ans << std::endl;

  return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 28300
final_rank: 11

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(ll i=0;i<(n);++i)
#define all(a) (a).begin(),(a).end()
using namespace std;
using Graph = vector<vector<int>>;
typedef pair<int,int> P;
typedef long long ll;

const ll INF = 1002003004005006007;

int main(){

    int n, m;
    cin >> n >> m;

    vector<vector<ll>> g(n, vector<ll> (n,INF));

    rep(i,m){
        int x, y, t; cin >> x >> y >> t;
        x--; y--;

        g[x][y] = t;
        g[y][x] = t;
    }

    //{距離, 今いる頂点, 速さ, 状態}
    using Q = tuple<ll, ll, ll, ll>;
    priority_queue<Q ,vector<Q>,greater<Q>> que;

    ll dp[505][55][2];
    rep(i,505)rep(j,55)rep(k,2) dp[i][j][k] = INF;

    ll v0; cin >> v0;
    int a, b, c; cin >> a >> b >> c;
    
    //初期push
    que.push(Q(0LL, 0LL, v0, 0LL));

    dp[0][v0][0] = 0;
    //Dijkstra
    while(!que.empty()){

        //まずはヒープの先頭の要素をとる
        auto e = que.top(); que.pop();

        //それぞれのパラメータを取得

        //auto [dist, v, velo, state] = e; // c++17
        ll dist, v, velo, state;
        tie(dist, v, velo, state) = e;

        //状態の遷移
        if (v == n - 1 and state == 0) {
            if (dp[v][velo][1] > dist) {
                dp[v][velo][1] = dist;
                que.push(Q(dist, v, velo, 1));
            }
        }

        // cout << "dist = " << dist << " , node = " << v + 1 << " , velo = " << velo << " state = " << state << endl;

        //次に行く頂点の距離が最小じゃなかったら論の外
        if(dist > dp[v][velo][state]) continue;


        for(int j = 0; j < n; j++){

            if(g[v][j] == INF) continue;

            //costをちゃんと計算しておく
            ll nvelo = (a * velo + b) % c;
            ll cost = g[v][j] * velo;

            //遷移
            if(dist + cost < dp[j][nvelo][state]){
                dp[j][nvelo][state] = dist + cost;
                que.push(Q(dist + cost, j, nvelo , state));
            }

        }
    }

    ll ans = INF;

    rep(i,51){
      ans = min(ans,dp[0][i][1]);
    }

    cout << ans << endl;
}
accuracy: 1
time_ms: 40
memory_kb: 12000
final_rank: 6

code_snippet: #include <iostream>
#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 <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <functional>
#include <bitset>

using namespace std;
using lint = long long int;
long long int INF = 5001001001001001LL;
int inf = 1000000007;
long long int MOD = 1000000007LL;
double PI = 3.1415926535897932;

template<typename T1,typename T2>inline void chmin(T1 &a,const T2 &b){if(a>b) a=b;}
template<typename T1,typename T2>inline void chmax(T1 &a,const T2 &b){if(a<b) a=b;}


#define rep(i,n) for(ll i=0;i<(n);++i)
#define all(a) (a).begin(),(a).end()
using namespace std;
using Graph = vector<vector<int>>;
typedef pair<int,int> P;
typedef long long ll;

#define int long long

signed main(){

    int n, m;
    cin >> n >> m;

    vector<vector<lint>> g(n, vector<lint> (n,INF));

    rep(i,m){
        int x, y, t; cin >> x >> y >> t;
        x--; y--;

        g[x][y] = t;
        g[y][x] = t;
    }

    //(距離, { {今いる頂点, 速さ} , 状態})

    // using Q = pair<ll, pair<pair<ll, ll>, ll> >;
    using Q = tuple<ll, ll, ll, ll>;
    priority_queue<Q ,vector<Q>,greater<Q>> que;

    ll dp[505][51][2];
    rep(i,505)rep(j,51)rep(k,2) dp[i][j][k] = INF;

    lint v0; cin >> v0;
    int a, b, c; cin >> a >> b >> c;
    // que.push (Q(0, {{0,v0}, 0}));
    que.push(Q(0LL, 0LL, v0, 0LL));

    dp[0][v0][0] = 0;
    //Dijkstra
    while(!que.empty()){
        //まずはヒープの先頭の要素をとる
        auto e = que.top(); que.pop();

        //それぞれのパラメータを取得
        // ll dist = e.first;
        // ll v = e.second.first.first;
        // ll velo = e.second.first.second;
        // ll state = e.second.second;
        
        //auto [dist, v, velo, state] = e; // c++17
        ll dist, v, velo, state;
        tie(dist, v, velo, state) = e;


        if (v == n - 1 and state == 0) {
          if (dp[v][velo][1] > dist) {
            dp[v][velo][1] = dist;
            que.push(Q(dist, v, velo, 1));
          }
        }

        // cout << "dist = " << dist << " , node = " << v + 1 << " , velo = " << velo << " state = " << state << endl;

        //次に行く頂点の距離が最小じゃなかったら論の外
        if(dist > dp[v][velo][state]) continue;


        for(int j = 0; j < n; j++){

            if(g[v][j] == INF) continue;

            ll nvelo = (a * velo + b) % c;
            ll cost = g[v][j] * velo;

            if(dist + cost < dp[j][nvelo][state]){
              dp[j][nvelo][state] = dist + cost;
              que.push(Q(dist + cost, j, nvelo , state));

            }
        }
    }

    ll ans = INF;

    rep(i,51){
        ans = min(ans,dp[0][i][1]);
    }

    cout << ans << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 11820
final_rank: 4

code_snippet: #include <iostream>
#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 <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <functional>
#include <bitset>

using namespace std;
using lint = long long int;
long long int INF = 5001001001001001LL;
int inf = 1000000007;
long long int MOD = 1000000007LL;
double PI = 3.1415926535897932;

template<typename T1,typename T2>inline void chmin(T1 &a,const T2 &b){if(a>b) a=b;}
template<typename T1,typename T2>inline void chmax(T1 &a,const T2 &b){if(a<b) a=b;}


#define rep(i,n) for(ll i=0;i<(n);++i)
#define all(a) (a).begin(),(a).end()
using namespace std;
using Graph = vector<vector<int>>;
typedef pair<int,int> P;
typedef long long ll;

#define int long long

signed main(){

    int n, m;
    cin >> n >> m;

    vector<vector<lint>> g(n, vector<lint> (n,INF));

    rep(i,m){
        int x, y, t; cin >> x >> y >> t;
        x--; y--;

        g[x][y] = t;
        g[y][x] = t;
    }

    //(距離, { {今いる頂点, 速さ} , 状態})
    using Q = pair<ll, pair<pair<ll, ll>, ll> >;
    priority_queue<Q ,vector<Q>,greater<Q>> que;

    ll dp[505][51][2];
    rep(i,505)rep(j,51)rep(k,2) dp[i][j][k] = INF;

    lint v0; cin >> v0;
    int a, b, c; cin >> a >> b >> c;
    que.push (Q(0, {{0,v0}, 0}));

    dp[0][v0][0] = 0;
    //Dijkstra
    while(!que.empty()){
        //まずはヒープの先頭の要素をとる
        auto e = que.top(); que.pop();

        //それぞれのパラメータを取得
        ll dist = e.first;
        ll v = e.second.first.first;
        ll velo = e.second.first.second;
        ll state = e.second.second;

        if (v == n - 1 and state == 0) {
          if (dp[v][velo][1] > dist) {
            dp[v][velo][1] = dist;
            que.push(Q(dist, {{v, velo}, 1}));
          }
        }

        // cout << "dist = " << dist << " , node = " << v + 1 << " , velo = " << velo << " state = " << state << endl;

        //次に行く頂点の距離が最小じゃなかったら論の外
        if(dist > dp[v][velo][state]) continue;


        for(int j = 0; j < n; j++){

            if(g[v][j] == INF) continue;

            ll nvelo = (a * velo + b) % c;

            if(dist + g[v][j] * velo < dp[j][nvelo][state]){
              dp[j][nvelo][state] = dist + g[v][j] * velo;
              que.push(Q( ( dist + g[v][j] * velo )  , {{j, nvelo} , state}));

            }
        }
    }

    ll ans = INF;

    rep(i,51){
        ans = min(ans,dp[0][i][1]);
    }

    cout << ans << endl;
}
accuracy: 1
time_ms: 40
memory_kb: 11780
final_rank: 5

code_snippet: #include <iostream>
#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 <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <functional>
#include <bitset>

using namespace std;
using lint = long long int;
long long int INF = 5001001001001001LL;
int inf = 1000000007;
long long int MOD = 1000000007LL;
double PI = 3.1415926535897932;

template<typename T1,typename T2>inline void chmin(T1 &a,const T2 &b){if(a>b) a=b;}
template<typename T1,typename T2>inline void chmax(T1 &a,const T2 &b){if(a<b) a=b;}


#define rep(i,n) for(ll i=0;i<(n);++i)
#define all(a) (a).begin(),(a).end()
using namespace std;
using Graph = vector<vector<int>>;
typedef pair<int,int> P;
typedef long long ll;

#define int long long

signed main(){

    int n, m;
    cin >> n >> m;

    vector<vector<lint>> g(n, vector<lint> (n,INF));

    rep(i,m){
        int x, y, t; cin >> x >> y >> t;
        x--; y--;

        g[x][y] = t;
        g[y][x] = t;
    }

    //(距離, { {今いる頂点, 速さ} , 状態})
    using Q = pair<ll, pair<pair<ll, ll>, ll> >;
    priority_queue<Q ,vector<Q>,greater<Q>> que;

    ll dp[505][51][2];
    rep(i,505)rep(j,51)rep(k,2) dp[i][j][k] = INF;

    lint v0; cin >> v0;
    int a, b, c; cin >> a >> b >> c;
    que.push (Q(0, {{0,v0}, 0}));

    dp[0][v0][0] = 0;
    //Dijkstra
    while(!que.empty()){
        //まずはヒープの先頭の要素をとる
        auto e = que.top(); que.pop();

        //それぞれのパラメータを取得
        ll dist = e.first;
        ll v = e.second.first.first;
        ll velo = e.second.first.second;
        ll state = e.second.second;

        if (v == n - 1 and state == 0) {
          if (dp[v][velo][1] > dist) {
            dp[v][velo][1] = dist;
            que.push(Q(dist, {{v, velo}, 1}));
          }
        }

        // cout << "dist = " << dist << " , node = " << v + 1 << " , velo = " << velo << " state = " << state << endl;

        //次に行く頂点の距離が最小じゃなかったら論の外
        if(dist > dp[v][velo][state]) continue;


        for(int j = 0; j < n; j++){

            if(g[v][j] == INF) continue;

            ll nvelo = (a * velo + b) % c;

            if(dist + g[v][j] * nvelo < dp[j][nvelo][state]){
              dp[j][nvelo][state] = dist + g[v][j] * velo;
              que.push(Q( ( dist + g[v][j] * velo )  , {{j, nvelo} , state}));

            }
        }
    }

    ll ans = INF;

    rep(i,51){
        ans = min(ans,dp[0][i][1]);
    }

    cout << ans << endl;
}
accuracy: 0.3448275862068966
time_ms: 10
memory_kb: 4312
final_rank: 20