#include <climits>
#include <iostream>
#include <vector>
#include <tuple>
#include <algorithm>


#define rep(i,i0,n) for (int (i) = (i0); (i) < (n); ++(i))

#define dp(i, j, k) dpt[N_LIMIT2 * (i) + N_LIMIT * (j) + (k)]

using namespace std;
using ll = long long;

const int M = 1e9 + 7;

const int N_LIMIT = 301;
const int N_LIMIT2 = N_LIMIT * N_LIMIT;

ll dpt[N_LIMIT2 * N_LIMIT];

class Comp {
public:
    bool operator() (const tuple<int, int, int> &lh, const tuple<int, int, int> &rh) {
        return get<1>(lh) < get<1>(rh);
    }
};

int solve(int n, int m, vector< tuple<int, int, int> > &lst) {

    int j;
    int r, g, b;
    int lj, rj, xj;
    ll ans;

    sort(lst.begin(), lst.end(), Comp());
    j = 0;

    fill(dpt, dpt + sizeof(dpt) / sizeof(dpt[0]), 0);
    dp(1, 0, 0) = 1;
    dp(0, 1, 0) = 1;
    dp(0, 0, 1) = 1;

    rep (i, 1, n + 1) {
        r = i - 1;
        rep (g, 0, i - 1) {
            rep (b, 0, i - 1) {
                dp(i, g, b) = (dp(i, g, b) + dp(r, g, b)) % M;
                dp(r, i, b) = (dp(r, i, b) + dp(r, g, b)) % M;
                dp(r, g, i) = (dp(r, g, i) + dp(r, g, b)) % M;
            }
        }
        g = i - 1;
        rep (r, 0, i - 1) {
            rep (b, 0, i - 1) {
                dp(i, g, b) = (dp(i, g, b) + dp(r, g, b)) % M;
                dp(r, i, b) = (dp(r, i, b) + dp(r, g, b)) % M;
                dp(r, g, i) = (dp(r, g, i) + dp(r, g, b)) % M;
            }
        }
        b = i - 1;
        rep (r, 0, i - 1) {
            rep (g, 0, i - 1) {
                dp(i, g, b) = (dp(i, g, b) + dp(r, g, b)) % M;
                dp(r, i, b) = (dp(r, i, b) + dp(r, g, b)) % M;
                dp(r, g, i) = (dp(r, g, i) + dp(r, g, b)) % M;
            }
        }
        while (j < m && get<1>(lst[j]) == i) {
            tie(lj, rj, xj) = lst[j];
            if (xj == 1) {
                rep (c1, lj, i) {
                    rep (c2, 0, i) {
                        dp(i, c1, c2) = 0;
                        dp(i, c2, c1) = 0;
                        dp(c1, i, c2) = 0;
                        dp(c2, i, c1) = 0;
                        dp(c1, c2, i) = 0;
                        dp(c2, c1, i) = 0;
                    }
                }
            } else if (xj == 2) {
                rep (c1, 0, lj) {
                    rep (c2, 0, lj) {
                        dp(i, c1, c2) = 0;
                        dp(c2, i, c1) = 0;
                        dp(c1, c2, i) = 0;
                    }
                }
                rep (c1, lj, i) {
                    rep (c2, lj, i) {
                        dp(i, c1, c2) = 0;
                        dp(c2, i, c1) = 0;
                        dp(c1, c2, i) = 0;
                    }
                }
            } else { // xj == 3
                rep (c1, 0, lj) {
                    rep (c2, 0, i) {
                        dp(i, c1, c2) = 0;
                        dp(i, c2, c1) = 0;
                        dp(c1, i, c2) = 0;
                        dp(c2, i, c1) = 0;
                        dp(c1, c2, i) = 0;
                        dp(c2, c1, i) = 0;
                    }
                }
            }
            ++j;
        }
    }

    ans = 0;
    rep (c1, 0, n) {
        rep (c2, 0, n) {
            ans += dp(n, c1, c2);
            ans += dp(c2, n, c1);
            ans += dp(c1, c2, n);
            ans %= M;
        }
    }
    
    return (int)ans;
}


int main(int argc, const char * argv[]) {
    int n, m;
    int li, ri, xi;
    vector< tuple<int, int, int> > lst;

    cin >> n >> m;
    rep (i, 0, m) {
        cin >> li >> ri >> xi;
        lst.push_back(make_tuple(li, ri, xi));
    }

    cout << solve(n, m, lst) << endl;

    return 0;
}


Measured memory_bytes: 213248