//#define DEBUG
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 
using namespace __gnu_pbds; 
using namespace std;
 
#define BSET(a, p) ((a) | (1ll << (p)))
#define BCHK(a, p) ((a) & (1ll << (p)))
#define BXOR(a, p) ((a) ^ (1ll << (p)));
#define BREM(a, p) (BCHK(a, p)?(BXOR(a, p)):(a))
#define BSHO(a, N) (bitset<N>(a))
 
#define fi first
#define sc second 
#define pb push_back
 
 
#ifdef DEBUG
    #define dbg(s) {s;}
    #define PRELUDE {common();}
#endif
 
#ifndef DEBUG 
    #define PRELUDE { common(); ios :: sync_with_stdio(false); cin.tie(0); cout.tie(0); }
    #define dbg(s)
    #define endl "\n"
#endif
 
#define int ll
#define i32 int32_t
 
#define RBTTYPE int
#define ordered_set tree<RBTTYPE, null_type, less<RBTTYPE>, rb_tree_tag,tree_order_statistics_node_update> 
// Ordered set docs:
// order_of_key (k) : Number of items strictly smaller than k .
// find_by_order(k) : K-th element in a set (counting from zero).
 
#define all(v) (v).begin(),(v).end()
 
typedef long long ll;
typedef long double ld;
typedef pair< int, int > pii;
typedef pair< ll, ll > pll;
 
istringstream _inp;
string _inps;

void common() {
    _inp.clear();
    _inps = "";
    _inp.str(_inps);
}

int gi() {
    int x;
    while (true) {
        try {
            while (_inp.peek() == ',' || _inp.peek() == ' ') 
                _inp.ignore();
            if (_inp >> x) 
                return x;
            else throw 6;
        } catch (...) {
            getline(cin, _inps);
            _inp.clear();
            _inp.str(_inps);
        }
    }
}

// To remove randomization use 0 below:
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
inline int ri(int x) { // from [0, n-1]
    return uniform_int_distribution<int>(0, x - 1)(rng);
}
 
inline ld rf() { // from [0, 1]
    return uniform_real_distribution<ld>(0, 1)(rng);
}
 
ll gcd(ll x, ll y) {
    if (x < y) return gcd(y, x);
    if (y == 0) return x;
    return gcd(y, x % y);
} 
 
const ll mod = 1e9 + 7;
 
ll modexp(ll x, ll ex) {
    ll ans = 1ll;
    while (ex > 0) {
        if (ex & 1ll) ans = (ans * x) % mod;
        ex >>= 1ll;
        x = (x * x) % mod;
    }
    return ans;
}
 
const int maxn = 5e3 + 7;
 
const ll inf = 1e9 + 7;

const int N = maxn;

int n,m;
vector<pii> qu;
int par[maxn];
int siz[maxn];
int dp[maxn][maxn];
int maxi[maxn];
vector<int> xc;

int _find(int x)
{
    if(par[x]==-1)
        return x;
    par[x] = _find(par[x]);
    return par[x];
}

void _dsu(int x, int y)
{
    x = _find(x);
    y = _find(y);
    if(x==y)
        return;
    if(siz[x]>siz[y])
    {
        siz[x]+=siz[y];
        par[y] = x;
    }
    else
    {
        siz[y]+=siz[x];
        par[x] = y;
    }
    return;
}

i32 main() {
    
    PRELUDE;
    cin>>n>>m;

    for(int i=1;i<=n;i++)
    {
        par[i] = -1;
        siz[i] = 0;
        maxi[i] = -1;
    }

    int l,r,u,v;
    string ty;
    qu.clear();
    for(int i=1;i<=m;i++)
    {
        cin>>l>>r>>ty;
        if(ty=="different")
        {
            qu.pb({l,r});
            continue;
        }
        for(int j = r;j>l;j--)
        {
            u = _find(l);
            v = _find(j);
            if(u==v)
                break;
            _dsu(u,v);
        }
    }

    for(int i=1;i<=n;i++)
    {
        if(par[i]==-1)
        {
            siz[i] = xc.size();
            xc.pb(i);
        }
    }

    for(auto y:qu)
    {
        u = _find(y.fi);
        v = _find(y.sc);
        if(u==v)
        {
            cout<<"0"<<endl;
            return 0;
        }
        u = siz[u];
        v = siz[v];
        assert(v>u);
        maxi[v] = max(maxi[v],u);
    }
    
    memset(dp,0,sizeof(dp));

    n = xc.size();
    //cout<<"newn"<<n<<endl;
    dp[0][1] = 2;
    int presum = 2;
    
    for(int i=1;i<n;i++)
    {
        dp[i][1] = presum;
        for(int len = 2;len<=i+1;len++)
        {
            dp[i][len] = dp[i-1][len-1];
        }
        u = i - maxi[i]+1;

        presum = 0;
        for(int len=1;len<=i+1;len++)
        {
            if(len>=u)
                dp[i][len] = 0;
            presum+=dp[i][len];
        }
        presum%=mod;
    }

    cout<<presum<<endl;

}