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 C++ (GCC 9.2.1) (judge verdict: Wrong Answer)

#include "bits/stdc++.h"
#define rep(i,n) for(int i = 0; i < (n); ++i)
using namespace std;
typedef long long int ll;
typedef pair<int, int> P;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

struct WeightedUnionFind {
    vector<int> data;
    vector<int> diff_weight;

    WeightedUnionFind(int sz) : data(sz, -1), diff_weight(sz, 0) {}

    bool unite(int x, int y, int w) {
        w += weight(x);
        w -= weight(y);
        x = find(x);
        y = find(y);
        bool is_union = (x != y);
        if (is_union) {
            if (data[x] > data[y]) {
                swap(x, y);
                w = -w;
            }
            data[x] += data[y];
            data[y] = x;
            diff_weight[y] = w;
        } else {
            if (diff(x, y) == w) return true;
        }
        return is_union;
    }

    int find(int x) {
        if (data[x] < 0) {
            return x;
        } else {
            int par = data[x];
            data[x] = find(data[x]); 
            diff_weight[x] += diff_weight[par];
            return data[x];
        }
    }

    int weight(int x) {
        find(x);
        return diff_weight[x];
    }

    bool same(int x, int y) {
        return find(x) == find(y);
    }

    int diff(int x, int y) {
        return weight(y) - weight(x);
    }

    int size(int x) {
        return -data[find(x)];
    }
};

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	int n, m, q;
	cin >> n >> m >> q;
	vector<pair<P, P>> a(q);
	rep(i,q){
		cin >> a[i].first.first >> a[i].first.second;
		cin >> a[i].second.first >> a[i].second.second;
		a[i].first.first--;
		a[i].first.second--;
	}
	int ans = 0;
	for(int S = 0; S < (1 << q); S++){
		int score = 0;
		WeightedUnionFind wuf(n);
		//int mi = n-1, ma = 0;
		rep(j,q){
			if(S>>j & 1){
				score += a[j].second.second;
				if(!wuf.unite(a[j].first.first, a[j].first.second, a[j].second.first)){
					score = -1;
					break;
				}
				/*
				chmin(mi, j);
				chmax(ma, j);
				*/
			}
		}
		/*
		if(mi != ma){
			if(wuf.diff(mi, ma) > m-1) continue;
		}
		*/
		chmax(ans, score);
	}
	cout << ans << endl;
	return 0;
}