#include using namespace std; using ll = long long; using ld = long double; using pii = pair; using pli = pair; using pll = pair; const string Yes="Yes"; const string No="No"; const string YES="YES"; const string NO="NO"; const string abc="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const ll MOD=1000000007; const ll mod=998244353; const ll big_prime=(1LL << 61)-1; const long long INF = 1LL << 60; const long double PI=3.141592653589793; #define pb push_back #define mp make_pair #define all(x) (x).begin(), (x).end() #define fi first #define se second #define YESNO(T) if(T){cout<<"YES"<>vec[i]; #define outV(vec) for(ll i=0;i inline bool chmax(T &a, T b) { return ((a < b) ? (a = b, true) : (false)); } template inline bool chmin(T &a, T b) { return ((a > b) ? (a = b, true) : (false)); } #pragma GCC target("avx") #pragma GCC optimize("O3") #pragma GCC optimize("unroll-loops") #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") #define rep(i, n) for (int i = 0; i < (int)(n); i++) //エラトステネスの篩 vectorPrime(2,false);//false=not Prime number, true=Prime Number void Era(ll N){ for(ll i=0;i 0) { if (n & 1) res = res * a % mod; a = a * a % mod; n >>= 1; } return res; } //素因数分解 vector > prime_factorize(long long N) { vector > res; for (long long a = 2; a * a <= N; ++a) { if (N % a != 0) continue; long long ex = 0; // 指数 // 割れる限り割り続ける while (N % a == 0) { ++ex; N /= a; } // その結果を push res.push_back({a, ex}); } // 最後に残った数について if (N != 1) res.push_back({N, 1}); return res; } //割り算 ll Div(ll a,ll b,ll m){ return (a * modpow(b,m-2,m)) % m; } //階乗 vectorfact(1); void fac(ll N,ll m){ fact[0]=1; for(int i=1;i<=N;i++){ fact.pb(fact[i-1]*(i)); fact[i]%=m; } } //組み合わせ ll comb(ll n,ll r,ll m){ return Div(fact[n],fact[r] * fact[n-r] % m,m); } //UnionFind struct UnionFind { vector par, rank, siz; // 構造体の初期化 UnionFind(int n) : par(n,-1), rank(n,0), siz(n,1) { } // 根を求める int root(int x) { if (par[x]==-1) return x; // x が根の場合は x を返す else return par[x] = root(par[x]); // 経路圧縮 } // x と y が同じグループに属するか (= 根が一致するか) bool same(int x, int y) { return root(x)==root(y); } // x を含むグループと y を含むグループを併合する bool unite(int x, int y) { int rx = root(x), ry = root(y); // x 側と y 側の根を取得する if (rx==ry) return false; // すでに同じグループのときは何もしない // union by rank if (rank[rx]>N>>M; vectorA(M); inV(A); ll ans=0; for(int i=0;i