#include<bits/stdc++.h>
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define never_give_up ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define len(x) (int)(x).size()
using namespace std;

typedef long long ll;
typedef long double ld;
const int mod = (int)1e9 + 7;
int get_answer(vector < ll > discard){
    int ans = 1;
    for(int i = 1; i < len(discard); ++i){
        ans = ((((discard[i]^(1ll*i*i))+1))%mod * 1ll * ans %mod);
    }
    return ans;
}
int solve(vector<int>a , vector<int>t){
//    cerr << " SOLVE \n";
    int n = len(a)-1;
    /// firstly let's assume who will win???
    ll suma=0,sumb=0;
    for(auto i = 1; i <= n; ++i){
        if(t[i] == 1)
            suma+=a[i];
        else
            sumb+=a[i];
    }
    int A,B;
//    cerr << suma << ' ' << sumb << endl;
    if(suma>sumb){
        /// then B-'a'
        B=1;
        A=2;
    }else{
        if(sumb > suma){
            B=2;
            A=1;
        }else{
            A=t[1];
            B=1^2^t[1];
        }
    }
    vector < ll > discard(n + 1);
    if(sumb == 0){
        discard[1] = 1;
        return get_answer(discard);
    }
    if(suma == 0){
        discard[1] = 1;
        return get_answer(discard);
    }
    vector < int > perm(n + 1);
    iota(all(perm) , 0);
    if(t[1] == B){
        a[1]--;
//        cerr << "here\n";
        /// find next A
        bool found=0;
        for(int j = 2; j <= n; ++j){
            if(t[j] == A){
                /// yo
                vector<int>nwa,nwt,nwperm;
                nwa.push_back(0);
                nwt.push_back(0);
                nwperm.push_back(0);
                for(int x = j; x <= n; ++x){
                    nwa.push_back(a[x]);
                    nwt.push_back(t[x]);
                    nwperm.push_back(x);
                }
                /// okay next is one
                discard[len(nwperm)] = 1;
                for(int x = 1; x < j; ++x){
                    nwa.push_back(a[x]);
                    nwt.push_back(t[x]);
                    nwperm.push_back(x);
                }

                a = nwa;
                t = nwt;
                perm = nwperm;
                found=1;
                break;
            }
        }
//        cerr << " end of here\n";
        assert(found);
    }
    /// first is t
    int cntA=0,cntB=0;
    ll sum=0;
    for(int i = 1; i <= n; ++i){
        if(t[i] == A)
            cntA++;
        else
            cntB++;
    }
    int assumed = 0;
    vector<bool>looked(n+1);
    int i = 1;


//    cerr << A << " " << B << endl;
//    for(int i = 1; i <= n; ++i)
//        cerr << t[i] << ' ';
//    cerr << '\n';
//    for(int i = 1; i <= n ;++i)
//        cerr << a[i] << ' ';
//    cerr << '\n';
//    cerr << suma << ' ' << sumb << endl;
    while(true){
        if(t[i] == A){
            if(!looked[i]){
                assumed++;
                looked[i]=1;
                sum += a[i];
                discard[i] = a[i];
            }
        }else{
            ll x = min(sum, (ll)a[i]);
            a[i] -= x;
            discard[i] += x;
            sum -= x;
        }
        if(assumed == cntA && sum == 0)
            break;
        i++;
        if(i == n + 1)
            i = 1;
    }
    vector < ll > totaldiscard(n+1);

    for(int i = 1; i <= n; ++i){
        totaldiscard[perm[i]] = discard[i];
    }
//    cerr << " total discrad\n";
//    for(int i = 1; i <= n; ++i)
//        cerr << totaldiscard[i] << ' ';
//    cerr << '\n';
//    cerr << " END SOLVE\n";
    return get_answer(totaldiscard);
}

int brute(vector<int>a,vector<int>t){
    int n = len(a) - 1;

    int type = t[1];
    int i = 1;
    vector < ll > discard(n + 1);
    while(true){
//        cerr << "1\n";
        /// find it
        bool found = 0;
        for(int x = 0 ; x < n + 1; ++x){
            if(a[i] > 0 && t[i] == type){
                found = 1;
                break;
            }
            i++;
            if(i == n + 1)
                i = 1;
        }
        if(!found)
            break;
        discard[i]++;
        a[i]--;
        type = (1 ^ 2 ^ type);

    }
    return get_answer(discard);
}
signed main(){
    never_give_up;
    int n;
    cin >> n;

    #ifndef LOCAL
    int m;
    cin >> m;
    vector < int > p(m+1),k(m+1),b(m+1),w(m+1);
    for(int i = 0 ; i < m; ++i){
        cin >> p[i+1] >> k[i+1] >> b[i+1] >> w[i+1];
    }
    int seed,base;
    seed = 0;
    base = 0;
    auto  rnd = [&](){
        int ret = seed;
        seed = (1ll * seed * base + 233) % 1000000007;
        return ret;
    };
    p[0] = 0;


    vector < int > a(n + 1) , t(n + 1);
    for(int i = 1; i <= m; ++i){
        seed = b[i];
        base = w[i];
        for(int j = p[i - 1] + 1; j <= p[i]; ++j){
            t[j] = (rnd() % 2) + 1;
            a[j] = (rnd() % k[i]) + 1;
        }
    }
    cout << solve(a , t);
    #else
        mt19937 rng(time(NULL));
        bool debug = 0;
        int T=1;
        vector < int > t(n + 1), a(n + 1);

        while((debug ? T-- : true)){
            if(debug){
                t = {0 , 1, 2, 1, 2, 2, 1};
                a = {0 , 1, 2, 5, 4, 1, 1};
            }else{
                for(int i = 1; i <= n; ++i)
                    t[i] = rng() % 2 + 1;
                for(int i = 1; i <= n; ++i)
                    a[i] = rng() % 10 + 1;
            }

//                cerr << "t \n";
//                for(int i =1; i <= n; ++i)
//                    cerr << t[i] << " ";
//                cerr << "\na\n";
//                for(int i = 1;i <= n; ++i)
//                    cerr << a[i] << " ";
//                cerr << '\n';

            if(brute(a , t) == solve(a , t)){
                cerr << "OK\n";
            }else{
                cerr << "WA\n";

                return 0;
            }

        }
    #endif


//    cout << solve(a , t) << ' ' << brute(a , t);
    return 0;
}
/*
t
1 2 1 2 2 1
a
1 2 5 4 1 1
*/
