时间限制:C/C++/Rust/Pascal 2秒,其他语言4秒
            空间限制:C/C++/Rust/Pascal 256 M,其他语言512 M
             64bit IO Format: %lld
        
     
    题目描述
        
        
    
            
            给出一个n个点的树,1号节点为根节点,每个点有一个权值
 你需要支持以下操作
 1.将以u为根的子树内节点(包括u)的权值加val 
  2.将(u, v)路径上的节点权值加val 
   3.询问(u, v)路径上节点的权值两两相乘的和 
 输入描述:
                                                    第一行两个整数n, m,表示树的节点个数以及操作个数
接下来一行n个数,表示每个节点的权值
接下来n - 1行,每行两个整数(u, v),表示(u, v)之间有边
接下来m行
开始有一个数opt,表示操作类型
若opt = 1,接下来两个整数表示u, val
若opt = 2,接下来三个整数表示(u, v), val
若opt = 3,接下来两个整数表示(u, v)
含义均如题所示
                                                                            输出描述:
                                                    对于每个第三种操作,输出一个数表示答案,对 取模
取模
                                                                            
                        
                            示例1
                        
                        
                            
                                输入
                                复制
                                
                                
                                    3 8
5 3 1
1 2
1 3
3 1 2
3 1 3
3 2 3
1 1 2
2 1 3 2
3 1 2
3 1 3
3 2 3
                                 
                             
                            
                                                            
                                    说明
                                    
                                        第一组询问结果:3 * 5 = 15
第二组询问结果:1 * 5 = 5
第三组询问结果:3 * 5 + 1 * 5 + 3 * 1 = 23
                                     
                                 
                                                     
                     
                                                        备注:
                对于 的数据,
的数据,
对于 的数据,
的数据,
设

表示读入的第i个节点的权值以及每次修改的权值,保证

保证不会有负数