#include using namespace std; class UnionFind{ private: vector par,siz; public: UnionFind(int N){ par.resize(N,-1); siz.resize(N,1); } int root(int x){ //連結成分の代表頂点を返す. if(par.at(x) == -1) return x; else return par.at(x) = root(par.at(x)); } bool unite(int u, int v){ //u,vを連結する 連結してた->false,した->trueを返す. u = root(u),v = root(v); if(u == v) return false; if(siz.at(u) < siz.at(v)) swap(u,v); //Union by size. par.at(v) = u; siz.at(u) += siz.at(v); return true; } bool issame(int u, int v){ //同じ連結成分ならtrue. if(root(u) == root(v)) return true; else return false; } int size(int pos){return siz.at(root(pos));} //posの連結成分の大きさを返す. }; long long mod = 998244353; //入力が必ず-mod= mod) v -= mod; return *this; } mint operator-=(const mint b){ v -= b.v; if(v < 0) v += mod; return *this; } mint operator*=(const mint b){v = v*b.v%mod; return *this;} mint operator/=(mint b){ if(b == 0) assert(false); int left = mod-2; while(left){if(left&1) *this *= b; b *= b; left >>= 1;} return *this; } mint operator++(){*this += 1; return *this;} mint operator--(){*this -= 1; return *this;} mint operator++(int){*this += 1; return *this;} mint operator--(int){*this -= 1; return *this;} bool operator==(const mint b){return v == b.v;} bool operator!=(const mint b){return v != b.v;} bool operator>(const mint b){return v > b.v;} bool operator>=(const mint b){return v >= b.v;} bool operator<(const mint b){return v < b.v;} bool operator<=(const mint b){return v <= b.v;} mint pow(long long n){ mint ret = 1,p = v; if(n < 0) p = p.inv(),n = -n; while(n){ if(n&1) ret *= p; p *= p; n >>= 1; } return ret; } mint inv(){return mint(1)/v;} }; int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); int N,M; cin >> N >> M; vector A(N); for(auto &a : A) cin >> a.v; vector answer(M); UnionFind Z(N); vector>> Graph(N); bool first = false; vector> hold; for(int i=0; i> u >> v; u--; v--; if(Z.issame(u,v)){hold.push_back({u,v,i}); continue;} Graph.at(u).push_back({v,i}); Graph.at(v).push_back({u,i}); Z.unite(u,v); } vector depth(N); { auto dfs = [&](auto dfs,int pos,int back,int dep) -> void { depth.at(pos) = dep; for(auto [to,e] : Graph.at(pos)) if(to != back) dfs(dfs,to,pos,dep+1); }; dfs(dfs,0,-1,0); } bool nibu = true; for(auto [u,v,i] : hold){ int len = (depth.at(u)+depth.at(v)+1); if(len%2 == 0) continue; nibu = false; Graph.at(u).push_back({v,i}); Graph.at(v).push_back({u,i}); break; } if(nibu){ auto dfs = [&](auto dfs,int pos,int back) -> mint { mint left = A.at(pos); for(auto [to,e] : Graph.at(pos)){ if(to == back) continue; mint k = dfs(dfs,to,pos); left -= k; answer.at(e) = k; } return left; }; if(dfs(dfs,0,-1) != 0) cout << "-1\n"; else for(int i=0; i already(N); { vector D(N); for(int i=0; i Q; for(int i=0; i> cycle; { for(int i=0; i=0; i--){ auto [pos,e] = cycle.at(i); if(i != n-1){ need = A.at(pos)-need; answer.at(e) = need; } else answer.at(e) = need; } for(int i=0; i