#include #include using namespace std; using namespace atcoder; using mint = modint1000000007; const int mod = 1000000007; //using mint = modint998244353; //const int mod = 998244353; //const int INF = 1e9; //const long long LINF = 1e18; //const bool debug = false; #define rep(i, n) for (int i = 0; i < (n); ++i) #define rep2(i,l,r)for(int i=(l);i<(r);++i) #define rrep(i, n) for (int i = (n-1); i >= 0; --i) #define rrep2(i,l,r)for(int i=(r-1);i>=(l);--i) #define all(x) (x).begin(),(x).end() #define allR(x) (x).rbegin(),(x).rend() //#define endl "\n" #define P pair template inline bool chmax(A & a, const B & b) { if (a < b) { a = b; return true; } return false; } template inline bool chmin(A & a, const B & b) { if (a > b) { a = b; return true; } return false; } struct S { mint sum, cost; }; struct F { mint x; }; S op(S sl, S sr) { return S{ sl.sum + sr.sum, sl.cost + sr.cost }; } S e() { return S{ 0, 0 }; } S mapping(F f, S s) { return S{ s.sum + s.cost * f.x, s.cost }; } F composition(F f, F g) { return F{ f.x + g.x }; } F id() { return F{ 0 }; } struct HeavyLightDecomposition { HeavyLightDecomposition(vector> &_g, vector&_val) :g(_g), val(_val) { n = g.size(); sz.resize(n); par.resize(n); in.resize(n); out.resize(n); rev.resize(n); head.resize(n); } int n; vector>g; vectorsz, par, in, out, rev, head; vectorval; lazy_segtree seg; void build() { dfs_sz(0); int time = 0; dfs_hld(0, time); initSegmentTree(); } void dfs_sz(int v, int p = -1) { par[v] = p; sz[v] = 1; if (g[v].size() && (p == g[v][0]))swap(g[v][0], g[v].back()); for (auto &e : g[v]) { if (p == e)continue; dfs_sz(e, v); sz[v] += sz[e]; if (sz[g[v][0]] < sz[e])swap(g[v][0], e); } } void dfs_hld(int v, int &time, int p = -1) { in[v] = time; time++; rev[in[v]] = v; for (auto &e : g[v]) { if (p == e)continue; if (e == g[v][0])head[e] = head[v]; else head[e] = e; dfs_hld(e, time, v); } out[v] = time; } void initSegmentTree() { vector_val(n); rep(i, n)_val[i] = val[rev[i]]; lazy_segtree _seg(_val); seg = _seg; } S query(int u, int v) { S ret = e(); for (;; v = par[head[v]]) { if (in[u] > in[v])swap(u, v); if (head[u] == head[v])break; auto get = seg.prod(in[head[v]], in[v] + 1); ret = op(ret, get); } auto get = seg.prod(in[u], in[v] + 1); ret = op(ret, get); return ret; } int la(int v, int k) { while (1) { int u = head[v]; if (in[v] - k > in[u])return rev[in[v] - k]; k -= in[v] - in[u] + 1; v = par[u]; } } int lca(int u, int v) { for (;; v = par[head[v]]) { if (in[u] > in[v])swap(u, v); if (head[u] == head[v])return u; } } // path update void update_path(int u, int v, F x) { for (;; v = par[head[v]]) { if (in[u] > in[v])swap(u, v); if (head[u] == head[v])break; seg.apply(in[head[v]], in[v] + 1, x); } seg.apply(in[u], in[v] + 1, x); } // subtree_update void update_subtree(int v, F x) { seg.apply(in[v], out[v], x); } void debug() { cout << "in" << endl; rep(i, n) cout << in[i] << " "; cout << endl; cout << "head" << endl; rep(i, n) cout << head[i] << " "; cout << endl; cout << "rev" << endl; rep(i, n) cout << rev[i] << " "; cout << endl; cout << "out" << endl; rep(i, n) cout << out[rev[i]] << " "; cout << endl; } }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; vectors(n), c(n); rep(i, n)cin >> s[i]; rep(i, n)cin >> c[i]; vector>g(n); rep(i, n - 1) { int u, v; cin >> u >> v; u--; v--; g[u].push_back(v); g[v].push_back(u); } vectorx(n); rep(i, n)x[i] = S{ s[i],c[i] }; HeavyLightDecomposition hld(g, x); hld.build(); //hld.debug(); int q; cin >> q; while (q--) { int t; cin >> t; if (0 == t) { int x, y, z; cin >> x >> y >> z; x--; y--; hld.update_path(x, y,F {z}); } else { int x, y; cin >> x >> y; x--; y--; S get = hld.query(x, y); cout << get.sum.val() << endl; } } return 0; }