Problem:
Score : 300 points

Problem Statement

Given are positive integers N, M, Q, and Q quadruples of integers ( a_i , b_i , c_i , d_i ).

Consider a sequence A satisfying the following conditions:

A is a sequence of N positive integers.

1 \leq A_1 \leq A_2 \le \cdots \leq A_N \leq M.

Let us define a score of this sequence as follows:

The score is the sum of d_i over all indices i such that A_{b_i} - A_{a_i} = c_i. (If there is no such i, the score is 0.)

Find the maximum possible score of A.

Constraints

All values in input are integers.

2 ≤ N ≤ 10

1 \leq M \leq 10

1 \leq Q \leq 50

1 \leq a_i < b_i \leq N ( i = 1, 2, ..., Q )

0 \leq c_i \leq M - 1 ( i = 1, 2, ..., Q )

(a_i, b_i, c_i) \neq (a_j, b_j, c_j) (where i \neq j)

1 \leq d_i \leq 10^5 ( i = 1, 2, ..., Q )

Input

Input is given from Standard Input in the following format:

N M Q
a_1 b_1 c_1 d_1
:
a_Q b_Q c_Q d_Q

Output

Print the maximum possible score of A.

Sample Input 1

3 4 3
1 3 3 100
1 2 2 10
2 3 2 10

Sample Output 1

110

When A = \{1, 3, 4\}, its score is 110. Under these conditions, no sequence has a score greater than 110, so the answer is 110.

Sample Input 2

4 6 10
2 4 1 86568
1 4 0 90629
2 3 0 90310
3 4 1 29211
3 4 3 78537
3 4 2 8580
1 2 1 96263
1 4 2 2156
1 2 0 94325
1 4 3 94328

Sample Output 2

357500

Sample Input 3

10 10 1
1 10 9 1

Sample Output 3

1

Solution in Java (OpenJDK 11.0.6) (judge verdict: Wrong Answer)

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.Iterator;

public class Main {

	static BufferedReader reader;
	final static boolean MODE_DEBUG = false;
	//static field here
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		reader = new BufferedReader(new InputStreamReader(System.in));
		//code here
		int[] NM = readLineInt();
		int N = NM[0];
		int M = NM[1];
		int Q = NM[2];
		int[][] a = new int[Q][4];
		int ans = 0;
		int max_point = 0;
		for(int k=0;k<Q;k++) {
			a[k] = readLineInt();
			max_point+=a[k][3];
			a[k][0]--;
			a[k][1]--;
		}
		Arrays.sort(a,new Comparator<int[]>(){

			@Override
			public int compare(int[] o1,int[] o2){ // TODO 自動生成されたメソッド・スタブ
			return o1[0]-o2[0]; }
		});
		
		ArrayList<Pattern> kouho = new ArrayList<>();
		Pattern p_init = new Pattern(Q,N);
		p_init.max_point = max_point;
		Arrays.fill(p_init.decided,-1);
		p_init.decided[0] = 1;
		kouho.add(p_init);
		int now_max = 0;
		while(kouho.size()>0) {
			Pattern p = kouho.remove(kouho.size()-1);
			if(p.point>now_max) {
				now_max = p.point;
			}
			if(p.max_point<=now_max) {
				continue;
			}
			for(int q=0;q<Q;q++) {
				if(!p.pattern_used[q]) {

					//do not use pattern
					Pattern p2 = new Pattern(p);
					p2.pattern_used[q] = true;
					//p2.pattern_type[q] = false;
					p2.max_point-=a[q][3];
					if(p2.max_point>now_max) {
						kouho.add(p2);
					}
					
					//use pattern
					if(p.decided[a[q][0]]!=-1) {
						if(p.decided[a[q][1]]==-1) {
							Pattern p1 = new Pattern(p);
							p1.pattern_used[q] = true;
							//p1.pattern_type[q] = true;
							p1.decided[a[q][1]] = p1.decided[a[q][0]]+a[q][2];
							if(p1.decided[a[q][1]]<=M) {
								p1.point+=a[q][3];
								kouho.add(p1);
							}
						}else if(p.decided[a[q][1]] == p.decided[a[q][0]]+a[q][2]) {
							Pattern p1 = new Pattern(p);
							p1.pattern_used[q] = true;
							//p1.pattern_type[q] = true;
							p1.point+=a[q][3];
							kouho.add(p1);
						}
					}else if(p.decided[a[q][1]]!=-1) {
						if(p.decided[a[q][0]]==-1) {
							Pattern p1 = new Pattern(p);
							p1.pattern_used[q] = true;
							//p1.pattern_type[q] = true;
							p1.decided[a[q][0]] = p1.decided[a[q][1]]-a[q][2];
							p1.point+=a[q][3];
							kouho.add(p1);
						}else if(p.decided[a[q][0]] == p.decided[a[q][1]]-a[q][2]) {
							Pattern p1 = new Pattern(p);
							p1.pattern_used[q] = true;
							//p1.pattern_type[q] = true;
							p1.point+=a[q][3];
							kouho.add(p1);
						}
					}
					break;
				}
			}
		}
		
		print(now_max);
	}
	
	//functions here
	//note that all methods should be STATIC


	private static <T> int arraySearch(T needle, T[] heystack) {
		for(int i=0;i<heystack.length;i++) {
			if(needle.equals(heystack[i])) {
				return i;
			}
		}
		return -1;
	}
	private static int[] sort(int[] base) {
		int[] copy = array_copy(base);
		Arrays.sort(copy);
		return copy;
	}
	private static int[] array_copy(int[] base) {
		int[] copy = new int[base.length];
		for(int i=0;i<base.length;i++) {
			copy[i] = base[i];
		}
		return copy;
	}
	private static int[] asArray(ArrayList<Integer> ints) {
		int[] intlist = new int[ints.size()];
		for(int i=0;i<intlist.length;i++) {
			intlist[i] = ints.get(i);
		}
		return intlist;
	}
	private static String[] readLine(){
		try{
			return reader.readLine().split(" ");
		}catch(Exception e){
			e.printStackTrace();
			return new String[]{e.getMessage()};
		}
	}
	private static int[] readLineInt(){
		try{
			String[] s = readLine();
			int[] ints = new int[s.length];
			for(int i=0;i<ints.length;i++) {
				ints[i] = Integer.parseInt(s[i]);
			}
			return ints;
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
	}
	private static byte[] readLineByte(){
		try{
			String[] s = readLine();
			byte[] bytes = new byte[s.length];
			for(int i=0;i<bytes.length;i++) {
				bytes[i] = Byte.parseByte(s[i]);
			}
			return bytes;
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
	}
	private static char[] readLineChar(){
		try{
			String[] s = readLine();
			char[] chars = new char[s.length];
			for(int i=0;i<chars.length;i++) {
				chars[i] = (char)Integer.parseInt(s[i]);
			}
			return chars;
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
	}
	private static void print(Object o){
		System.out.println(o);
	}
	private static void print(){
		System.out.println();
	}
	private static void printd(Object o){
		if(MODE_DEBUG)System.err.println(o);
	}
	private static void printd(){
		if(MODE_DEBUG)System.err.println();
	}
}

class Pattern{
	boolean[] pattern_used;
	//boolean[] pattern_type;
	int point;
	int max_point;
	int[] decided;
	
	
	public Pattern(int Q, int N){
		// TODO 自動生成されたコンストラクター・スタブ
		pattern_used = new boolean[Q];
		//pattern_type = new boolean[Q];
		decided = new int[N];
	}
	public Pattern(Pattern copy) {
		this.pattern_used = Arrays.copyOf(copy.pattern_used,copy.pattern_used.length);
		//this.pattern_type = Arrays.copyOf(copy.pattern_type,copy.pattern_type.length);
		this.point = copy.point;
		this.max_point = copy.max_point;
		this.decided = Arrays.copyOf(copy.decided,copy.decided.length);
	}
}