# input import sys input = sys.stdin.readline II = lambda : int(input()) MI = lambda : map(int, input().split()) LI = lambda : [int(a) for a in input().split()] SI = lambda : input().rstrip() LLI = lambda n : [[int(a) for a in input().split()] for _ in range(n)] LSI = lambda n : [input().rstrip() for _ in range(n)] MI_1 = lambda : map(lambda x:int(x)-1, input().split()) LI_1 = lambda : [int(a)-1 for a in input().split()] mod = 998244353 inf = 1001001001001001001 ordalp = lambda s : ord(s)-65 if s.isupper() else ord(s)-97 ordallalp = lambda s : ord(s)-39 if s.isupper() else ord(s)-97 yes = lambda : print("Yes") no = lambda : print("No") yn = lambda flag : print("Yes" if flag else "No") prinf = lambda ans : print(ans if ans < 1000001001001001001 else -1) alplow = "abcdefghijklmnopqrstuvwxyz" alpup = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" alpall = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" URDL = {'U':(-1,0), 'R':(0,1), 'D':(1,0), 'L':(0,-1)} DIR_4 = [[-1,0],[0,1],[1,0],[0,-1]] DIR_8 = [[-1,0],[-1,1],[0,1],[1,1],[1,0],[1,-1],[0,-1],[-1,-1]] DIR_BISHOP = [[-1,1],[1,1],[1,-1],[-1,-1]] prime60 = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59] sys.set_int_max_str_digits(0) # sys.setrecursionlimit(10**6) # import pypyjit # pypyjit.set_param('max_unroll_recursion=-1') from collections import defaultdict,deque from heapq import heappop,heappush from bisect import bisect_left,bisect_right DD = defaultdict BSL = bisect_left BSR = bisect_right class DualSegTree: def __init__(self, op, e, lst): self.n = len(lst) self.log = (self.n - 1).bit_length() self.size = 1 << self.log self.op = op self.e = e self.data = [e] * (2 * self.size) for i in range(self.n): self.data[self.size + i] = lst[i] def propagate(self, k): if self.data[k] != self.e: self.data[2*k] = self.op(self.data[2*k], self.data[k]) self.data[2*k+1] = self.op(self.data[2*k+1], self.data[k]) self.data[k] = self.e def get(self, i): i += self.size for d in range(1, self.log + 1): self.propagate(i >> d) return self.data[i] def apply(self, l, r, f): l += self.size r += self.size for d in range(self.log, 0, -1): if ((l >> d) << d) != l: self.propagate(l >> d) if ((r >> d) << d) != r: self.propagate((r - 1) >> d) while l < r: if l & 1: self.data[l] = self.op(self.data[l], f) l += 1 if r & 1: r -= 1 self.data[r] = self.op(self.data[r], f) l >>= 1 r >>= 1 def __str__(self): for i in range(1, 2 * self.n0): self.propagate(i) return self.data[self.size:self.size+self.n] n, b, q = MI() lim = 110 comb = [[0] * lim for i in range(lim)] for i in range(lim): comb[i][0] = 1 for j in range(1, i + 1): comb[i][j] = (comb[i-1][j-1] + comb[i-1][j]) % b seg = [DualSegTree(lambda x, y : (x + y) % b, 0, [0] * n) for i in range(lim)] for _ in range(q): l, m, r, c, d = MI() l -= 1 m -= 1 p = 1 for i in reversed(range(d + 1)): seg[i].apply(l, r, comb[d][i] * p % b) p = p * c % b p = 1 ans = 0 for i in range(lim): ans += p * seg[i].get(m) % b p = p * (m + 1) % b ans %= b print(ans) # for i in range(lim): # print(seg[i])