#include <cstdio>
#include <vector>
#include <stack>

using namespace std;

#define MAXM 100000
#define MAXN 100000
#define NONE -1
#define NUM_TREES 20

struct Node
{
	int from,to;
	long long n,sum,baggage;
	Node *left,*right;
	
	Node();
	void init(int,int,Node*,Node*);
	void pass();
	bool inside(int,int); //node is inside interval
	bool outside(int,int); //node is outside interval
	
} trees[NUM_TREES][MAXM<<1];
int treeN[NUM_TREES];
Node *root;

int N,M;
int ar[MAXN];

Node :: Node() { baggage=0; }
void Node :: init(int a, int b, Node *l=NULL, Node *r=NULL) { from=a; to=b; if(a==b) { sum=ar[a]; n=1; } else { n=l->n+r->n; sum=l->sum+r->sum; } left=l; right=r; }
void Node :: pass() { if(left) { left->baggage += baggage; right->baggage += baggage; } sum+=baggage*n; baggage=0; }
bool Node :: inside(int a, int b) { return(a<=from and b>=to); }
bool Node :: outside(int a, int b) { return(a>to or b<from); }

Node *newNode (int treeIdx) { return &trees[treeIdx][treeN[treeIdx]++]; }

Node *buildTree(int from, int to, int treeIdx)
{
	Node *ret=newNode(treeIdx);
	if(from==to) ret->init(from,to);
	else
	{
		int mid=(from+to)/2;
		ret -> init(from,to, buildTree(from,mid,treeIdx), buildTree(mid+1,to,treeIdx));
	}
	return ret;
}

void add(Node *cur, int from, int to, long long v)
{
	cur->pass();
	if(cur->outside(from,to)) return;
	if(cur->inside(from,to))
	{
		cur->baggage += v;
		cur->pass();
		return;
	}
	add(cur->left, from,to,v); add(cur->right, from,to,v);
	cur->sum = cur->left->sum + cur->right->sum;
}

long long getSum(Node *cur, int from, int to)
{
	cur->pass();
	if(cur->outside(from,to)) return 0;
	if(cur->inside(from,to)) { cur->pass(); return cur->sum; }
	return getSum(cur->left, from,to) + getSum(cur->right, from,to);
}

long long S;
int p[MAXN],l[MAXN],r[MAXN],v[MAXN];
vector< stack<Node*> > idxTrees;
int ahN=1;

long long intersection(int a, int b, int c, int d)
{
	if(b<c or a>d) return 0;
	if(a<=c)
	{
		if(b<=d) return (b-c+1);
		return (d-c+1);
	}
	if(b<=d) return (b-a+1);
	return (d-a+1);
}

void init()
{
	scanf("%d %d", &N, &M);
	for(int i=0; i<M; i++) scanf("%d", &ar[i]);
	root = buildTree(0,M-1,0);
	
	stack<Node*> emptyStack;
	for(int i=0; i<N; i++) idxTrees.push_back(emptyStack);
	
	for(int i=1; i<NUM_TREES; i++) idxTrees[0].push(buildTree(0,M-1,i));
}

void solve()
{
	S=0;
	p[0]=NONE;
	
	int X,Y,V,Z,T;
	int L,R,I,J;
	int idx;
	
	
	for(int i=1; i<N; i++)
	{
		scanf("%d %d %d %d %d %d", &p[i], &X, &Y, &V, &Z, &T);
		p[i]--;
		//printf("Town #%d...\n", i);
		//printf("  parent: #%d\n", p[i]);
		L = ((X+S)%M);
		R = ((Y+S)%M);
		I = ((Z+S)%M);
		J = ((T+S)%M);
		if(I>J) swap(I,J);
		if(L>R) swap(L,R);
		//printf("  (%d - %d) (%d - %d) %d\n", L,R, I,J, V);
		l[i]=L; r[i]=R; v[i]=V;
		
		if(!idxTrees[p[i]].empty())
		{
			//printf("  *using existing tree\n");
			idxTrees[i].push( idxTrees[p[i]].top() );
			idxTrees[p[i]].pop(); //"move" index tree
			
			//printf("  sum was %d\n", getSum(idxTrees[i].top(), 0,M-1));
			add(idxTrees[i].top(), L,R, (long long)V);
			//printf("  now it's %d\n", getSum(idxTrees[i].top(), 0,M-1));
			S = getSum(idxTrees[i].top(), I,J);
		}
		else
		{
			idx = i;
			S = 0;
			while(idx != NONE)
			{
				S += intersection(I,J, l[idx],r[idx])*v[idx];
				idx = p[idx];
			}
			S += getSum(root, I,J);
		}
		printf("%lld\n", S);
	}
}

int main()
{
	//freopen("ants0.in", "r", stdin);
	init();
	solve();
	
	return 0;
}
