Problem:
Problem J: J's Final Problem
Problem
不思議なダンジョンとは構造の変化を伴うダンジョンである。不思議なダンジョンは階層が深いものから浅いものまで様々なものがあり、深い階層には凶悪なモンスターが生息していたり、財宝が眠っていたりする。ジェイは不思議なダンジョンを研究している研究者である。ある日、新しいダンジョンを掘っていたところ、とても大きく深いダンジョンに繋がってしまった。ジェイはこのダンジョンを「ジェイの最終問題」と名付けた。このダンジョンの調査が、優秀な冒険者であるあなたに依頼されることになった。冒険者の目的はできるだけ深い層のフロアに到達することである。このダンジョンの特徴を以下に述べる。
地上からダンジョンの地下1階の部屋への下りの階段は1つしか存在しない。
各部屋は1つの上りの階段と2つの下りの階段が存在する。
2つの下りの階段のうち片方を右の階段、もう片方を左の階段とする。
冒険者が階段を降りた際に、ダンジョンの構造が変化することがある。
階段を降りるとは、地下
i
階のある部屋から地下
i
+1階のある部屋へ降りることを示す。
階段を上った場合はダンジョンに対して何も変化を及ぼさない。
地下
n
階目には階段は存在しない。
最近、ジェイの最終問題に関する石碑が発見された。
どうやら、各階の階段を降りたときの変化がメモとして記されているようだ。

メモの形式は、
num1
direction1
:
num2
direction2
という形である。

地下
num1
階のすべての部屋について、direction1の階段を降りている途中で、地下num2階のすべての部屋について、 direction2の階段を降りた先の部屋が消滅し、さらにそこから階段を降りることによって到達できる部屋や階段がすべて消滅する。部屋や階段の消滅に冒険者が巻き込まれた場合、冒険は失敗する。地下
i
階から地下
i
+1階へ向かう階段の途中で冒険者が失敗した場合は地下
i
階まで到達したものとして扱う。

石碑において言及されていない階段は、その階段を降りてもダンジョンの構造に変化を及ぼさないことを示す。
冒険者はこの石碑をヒントにして探索を行うことにした。
ダンジョンの深さ
n
とメモの情報が
m
個与えられるので、最大地下何階まで到達できるかを答えなさい。
Input
入力は複数のデータセットからなる。
n
m
memo
1
memo
2
…
memo
m
最初に
n
,
m
が与えられる。
それぞれ、ダンジョンの変化前の最下層の階数、石碑のメモの数を表す。
次に
m
行にわたりメモの情報
num1
direction1
:
num2
direction2
が与えられる。
Constraints
入力は以下の条件を満たす。
入力に含まれる値はすべて整数
1 ≤
n
≤ 10000
0 ≤
m
≤ (
n
-1)×4
1 ≤
num1
,
num2
≤
n
-1
direction1,direction2は"left"と"right"のいずれかである。
Output
最大地下何階まで降りることができるか1行に出力して答えよ。
Sample Input1
10 2
9 left : 9 left
9 right : 9 right
Sample Output1
9
Sample Input2
4 5
1 left : 2 right
2 left : 3 right
2 left : 3 left
1 right : 3 left
2 right : 3 right
Sample Output2
3

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
struct SCC{
  int n;
  vector<vector<int> > G,rG,T,C;
  vector<int> vs,used,belong;
  SCC(){}
  SCC(int sz):n(sz),G(sz),rG(sz),used(sz),belong(sz){}
   
  void add_edge(int from,int to){
    G[from].push_back(to);
    rG[to].push_back(from);
  }
   
  void input(int m,int offset=0){
    int a,b;
    for(int i=0;i<m;i++){
      cin>>a>>b;
      add_edge(a+offset,b+offset);
    }
  }
   
  void dfs(int v){
    used[v]=1;
    for(int i=0;i<(int)G[v].size();i++){
      if(!used[G[v][i]]) dfs(G[v][i]);
    }
    vs.push_back(v);
  }
   
  void rdfs(int v,int k){
    used[v]=1;
    belong[v]=k;
    C[k].push_back(v);
    for(int i=0;i<(int)rG[v].size();i++){
      if(!used[rG[v][i]]) rdfs(rG[v][i],k);
    }
  }
   
  int build(){
    fill(used.begin(),used.end(),0);
    vs.clear();
    for(int v=0;v<n;v++){
      if(!used[v]) dfs(v);
    }
    fill(used.begin(),used.end(),0);
    int k=0;
    for(int i=vs.size()-1;i>=0;i--){
      if(!used[vs[i]]){
    T.push_back(vector<int>());
    C.push_back(vector<int>());
    rdfs(vs[i],k++);
      }
    }
    for(int i=0;i<n;i++)
      for(int u:G[i])
    if(belong[i]!=belong[u])
      T[belong[i]].push_back(belong[u]);
    for(int i=0;i<k;i++){
      sort(T[i].begin(),T[i].end());
      T[i].erase(unique(T[i].begin(),T[i].end()),T[i].end());
    }
    return k;
  }
};
signed main(){
  int n,m;
  cin>>n>>m;
  int V = n*2;
  vector<vector<int> > G(V);
   
  int l=0,r=n;
  for(int i=0;i<m;i++){
    int x,y;
    string s,t,u;
    cin>>x>>s>>u>>y>>t;
    x--;y--;
    if(s=="right") x+=n;
    if(t=="right") y+=n;
    G[x].emplace_back((y+n)%V);
    G[y].emplace_back((x+n)%V);
  }
   
  auto check=[&](int x)->int{
    SCC scc(V);
    for(int i=0;i<x;i++)
      for(int v=i;v<V;v+=n)
    for(int u:G[v])
      if(u%n<x) scc.add_edge(v,u);
     
    scc.build();
    for(int i=0;i<x;i++)
      if(scc.belong[i]==scc.belong[i+n]) return 0;
    return 1;
  };
   
  while(l+1<r){
    int m=(l+r)>>1;
    if(check(m)) l=m;
    else r=m;
  }
  cout<<r<<endl;
  return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 8068
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
struct SCC{
  int n;
  vector<vector<int> > G,rG,T,C;
  vector<int> vs,used,belong;
  SCC(){}
  SCC(int sz):n(sz),G(sz),rG(sz),used(sz),belong(sz){}
  
  void add_edge(int from,int to){
    G[from].push_back(to);
    rG[to].push_back(from);
  }
  
  void input(int m,int offset=0){
    int a,b;
    for(int i=0;i<m;i++){
      cin>>a>>b;
      add_edge(a+offset,b+offset);
    }
  }
  
  void dfs(int v){
    used[v]=1;
    for(int i=0;i<(int)G[v].size();i++){
      if(!used[G[v][i]]) dfs(G[v][i]);
    }
    vs.push_back(v);
  }
  
  void rdfs(int v,int k){
    used[v]=1;
    belong[v]=k;
    C[k].push_back(v);
    for(int i=0;i<(int)rG[v].size();i++){
      if(!used[rG[v][i]]) rdfs(rG[v][i],k);
    }
  }
  
  int build(){
    fill(used.begin(),used.end(),0);
    vs.clear();
    for(int v=0;v<n;v++){
      if(!used[v]) dfs(v);
    }
    fill(used.begin(),used.end(),0);
    int k=0;
    for(int i=vs.size()-1;i>=0;i--){
      if(!used[vs[i]]){
	T.push_back(vector<int>());
	C.push_back(vector<int>());
	rdfs(vs[i],k++);
      }
    }
    for(int i=0;i<n;i++)
      for(int u:G[i])
	if(belong[i]!=belong[u])
	  T[belong[i]].push_back(belong[u]);
    for(int i=0;i<k;i++){
      sort(T[i].begin(),T[i].end());
      T[i].erase(unique(T[i].begin(),T[i].end()),T[i].end());
    }
    return k;
  }
};
signed main(){
  int n,m;
  cin>>n>>m;
  int V = n*2;
  vector<vector<int> > G(V);
  
  int l=0,r=n;
  for(int i=0;i<m;i++){
    int x,y;
    string s,t,u;
    cin>>x>>s>>u>>y>>t;
    x--;y--;
    if(s=="right") x+=n;
    if(t=="right") y+=n;
    G[x].emplace_back((y+n)%V);
    G[y].emplace_back((x+n)%V);
  }
  
  auto check=[&](int x)->int{
    SCC scc(V);
    for(int i=0;i<x;i++)
      for(int v=i;v<V;v+=n)
	for(int u:G[v])
	  if(u%n<x) scc.add_edge(v,u);
    
    scc.build();
    for(int i=0;i<x;i++)
      if(scc.belong[i]==scc.belong[i+n]) return 0;
    return 1;
  };
  
  while(l+1<r){
    int m=(l+r)>>1;
    if(check(m)) l=m;
    else r=m;
  }
  cout<<r<<endl;
  return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 8060
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcount

#define INF 1e16
#define mod 1000000007

int n,m;
vector<P> es;
int addnot;
int v1[80010],v2[80010];

int V;
vector<int> g[80010],rg[80010];
vector<int> vs;
bool used[80010];
int cmp[80010];

void add_edge(int from,int to){
  g[from].push_back(to);
  rg[to].push_back(from);
}

void dfs(int v){
  used[v]=true;
  for(int i=0;i<g[v].size();i++){
    if(!used[g[v][i]])dfs(g[v][i]);
  }
  vs.push_back(v);
}

void rdfs(int v,int k){
  used[v]=true;
  cmp[v]=k;
  for(int i=0;i<rg[v].size();i++){
    if(!used[rg[v][i]])rdfs(rg[v][i],k);
  }
}

int scc(){
  memset(used,0,sizeof(used));
  vs.clear();
  for(int v=0;v<V;v++){
    if(!used[v])dfs(v);
  }
  memset(used,0,sizeof(used));
  int k=0;
  for(int i=vs.size()-1;i>=0;i--){
    if(!used[vs[i]])rdfs(vs[i],k++);
  }
  return k;
}

bool ok(int x){
  rep(i,V){
    g[i].clear();
    rg[i].clear();
  }
  rep(i,es.size()){
    if(v1[i]<x&&v2[i]<x)add_edge(es[i].fi,es[i].se);
  }
  scc();
  bool ok=true;
  rep(i,n){
    if(cmp[i]==cmp[i+addnot])ok=false;
  }
  return ok;
}

int main(){
  cin>>n>>m;
  addnot=n;
  V=n*2;
  rep(i,m){
    int a1,a2;
    string d1,d2,c;
    cin>>a1>>d1>>c>>a2>>d2;
    a1--; a2--;
    v1[i*2]=a1; v2[i*2]=a2;
    es.push_back(P(a1+(d1=="left"?addnot:0),a2+(d2=="left"?0:addnot)));
    v1[i*2+1]=a2; v2[i*2+1]=a1;
    es.push_back(P(a2+(d2=="left"?addnot:0),a1+(d1=="left"?0:addnot)));
  }
  int lb=0,ub=n;
  while(ub-lb>1){
    int mid=(lb+ub)/2;
    if(ok(mid))lb=mid;
    else ub=mid;
  }
  cout<<ub<<endl;
  return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 9572
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

struct SCC{
    int V;
    vector<vector<int>> G, rG;
    vector<int> vs; // 帰りがけ順の並び
    vector<int> cmp; //属する強連結成分トポロジカル順序
    vector<bool> used;

    SCC(){}
    SCC(int n){
        V = n;
        G = vector<vector<int>>(n);
        rG = vector<vector<int>>(n);
    }

    void add_edge(int from, int to){
        G[from].push_back(to);
        rG[to].push_back(from);
    }

    void dfs(int v){
        used[v] = true;
        rep(i,G[v].size())if(!used[G[v][i]]) dfs(G[v][i]);
        vs.push_back(v);
    }

    void rdfs(int v, int k){
        used[v]=true;
        cmp[v]=k;
        rep(i,rG[v].size())if(!used[rG[v][i]]) rdfs(rG[v][i],k);
    }

    int scc(){
        used = vector<bool>(V,false);
        vs.clear();
        rep(i,V)if(!used[i]) dfs(i);

        used = vector<bool>(V,false);
        cmp = vector<int>(V);
        int num_scc = 0;
        for(int i=vs.size()-1; i>=0; --i)if(!used[vs[i]]) rdfs(vs[i],num_scc++);
        return num_scc;
    }
};

struct TwoSat{
    int v;
    SCC graph;

    // v literals
    // 0~v-1: true
    // v~2v-1: false

    TwoSat(int num_literal){
        v = num_literal;
        graph = SCC(2*v);
    }

    inline int num(int id, bool b){return id+(b?0:v);}

    void add_clause(int x, bool X, int y, bool Y){
        graph.add_edge(num(x,!X), num(y,Y));
        graph.add_edge(num(y,!Y), num(x,X));
    }

    // 割り当てが可能か調べる
    bool calc(){
        graph.scc();
        rep(i,v)if(graph.cmp[i]==graph.cmp[v+i]) return false;
        return true;
    }

    // リテラルの真偽値を返す
    vector<bool> get_literals(){
        assert(calc());
        vector<bool> res(v);
        rep(i,v) res[i] = (graph.cmp[i]>graph.cmp[v+i]);
        return res;
    }
};

// (floor, left/right)
using pi = pair<int,int>;

pi READ(){
    int num;
    string lr;
    cin >>num >>lr;

    return {num, (lr=="right")};
}

int main(){
    int n,m;
    cin >>n >>m;

    vector<pair<pi,pi>> v(m);
    rep(i,m){
        char sep;
        pi x,y;

        x = READ();
        cin >>sep;
        y = READ();

        v[i] = {x,y};
    }

    auto valid = [&](int c){
        const int N = 10010;
        TwoSat t(N);
        rep(i,m){
            pi x = v[i].fi, y = v[i].se;
            if(x.fi<c && y.fi<c){
                t.add_clause(x.fi, !x.se, y.fi, !y.se);
            }
        }

        return t.calc();
    };

    int l=1, r=n+1;
    while(r-l>1){
        int mid = (l+r)/2;
        if(valid(mid)) l=mid;
        else r=mid;
    }
    cout << l << endl;
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 5340
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define R cin>>
#define Z class
#define ll long long
#define ln cout<<'\n'
#define in(a) insert(a)
#define pb(a) push_back(a)
#define pd(a) printf("%.10f\n",a)
#define mem(a) memset(a,0,sizeof(a))
#define all(c) (c).begin(),(c).end()
#define iter(c) __typeof((c).begin())
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;i--)
#define REP(i,m,n) for(int i=(int)(m);i<(int)(n);i++)
#define rep(i,n) REP(i,0,n)
#define tr(it,c) for(iter(c) it=(c).begin();it!=(c).end();it++)
template<Z A>void pr(A a){cout<<a;ln;}
template<Z A,Z B>void pr(A a,B b){cout<<a<<' ';pr(b);}
template<Z A,Z B,Z C>void pr(A a,B b,C c){cout<<a<<' ';pr(b,c);}
template<Z A,Z B,Z C,Z D>void pr(A a,B b,C c,D d){cout<<a<<' ';pr(b,c,d);}
template<Z A>void PR(A a,ll n){rep(i,n){if(i)cout<<' ';cout<<a[i];}ln;}
ll check(ll n,ll m,ll x,ll y){return x>=0&&x<n&&y>=0&&y<m;}
const ll MAX=1000000007,MAXL=1LL<<61,dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
typedef pair<int,int> P;
typedef pair<P,P> PP;
#define N 200001
vector<int> G[N],rG[N],g;
bool u[N];
int n,cmp[N];

void add_edge(int x,int y){G[x].push_back(y);rG[y].push_back(x);}
void dfs(int x){u[x]=1;rep(i,G[x].size())if(!u[G[x][i]])dfs(G[x][i]);g.push_back(x);} 
void rdfs(int x,int k){u[x]=1;cmp[x]=k;rep(i,rG[x].size())if(!u[rG[x][i]])rdfs(rG[x][i],k);}
int scc() {
  mem(u);g.clear();rep(i,n)if(!u[i])dfs(i);mem(u);
  int k=0;rrep(i,g.size())if(!u[g[i]])rdfs(g[i],k++);return k;
}
void init() {
  rep(i,n) G[i].clear(),rG[i].clear();
  g.clear();
}
int rev(int x) {return (x+n/2)%n;}
int two_sat(vector<P> v) {
  init();
  rep(i,v.size()) {
    add_edge(rev(v[i].F),v[i].S);
    add_edge(rev(v[i].S),v[i].F);
  }
  scc();
  rep(i,n/2) {
    if(cmp[i]==cmp[i+n/2]) return 0;
  }
  return 1;
}
void Main() {
  int m;
  cin >> n >> m;
  PP a[m];
  rep(i,m) {
    int x,y;
    string s,t,r;
    cin >> x >> s >> t >> y >> r;
    x--,y--;
    a[i]=PP(P(x,s=="left"?0:1),P(y,r=="left"?0:1));
  }
  int l=0,r=n;
  while(l+1<r) {
    int mid=(l+r)/2;
    n=mid*2;
    vector<P> v;
    rep(i,m) {
      int x=a[i].F.F,y=a[i].S.F;
      if(x>=mid||y>=mid) continue;
      if(a[i].F.S) x=rev(x);
      if(a[i].S.S) y=rev(y);
      v.pb(P(x,y));
    }
    if(two_sat(v)) l=mid;
    else r=mid;
  }
  cout << r << endl;
}

int main(){ios::sync_with_stdio(0);cin.tie(0);Main();return 0;}
accuracy: 1
time_ms: 30
memory_kb: 14396
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define R cin>>
#define Z class
#define ll long long
#define ln cout<<'\n'
#define in(a) insert(a)
#define pb(a) push_back(a)
#define pd(a) printf("%.10f\n",a)
#define mem(a) memset(a,0,sizeof(a))
#define all(c) (c).begin(),(c).end()
#define iter(c) __typeof((c).begin())
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;i--)
#define REP(i,m,n) for(int i=(int)(m);i<(int)(n);i++)
#define rep(i,n) REP(i,0,n)
#define tr(it,c) for(iter(c) it=(c).begin();it!=(c).end();it++)
template<Z A>void pr(A a){cout<<a;ln;}
template<Z A,Z B>void pr(A a,B b){cout<<a<<' ';pr(b);}
template<Z A,Z B,Z C>void pr(A a,B b,C c){cout<<a<<' ';pr(b,c);}
template<Z A,Z B,Z C,Z D>void pr(A a,B b,C c,D d){cout<<a<<' ';pr(b,c,d);}
template<Z A>void PR(A a,ll n){rep(i,n){if(i)cout<<' ';cout<<a[i];}ln;}
ll check(ll n,ll m,ll x,ll y){return x>=0&&x<n&&y>=0&&y<m;}
const ll MAX=1000000007,MAXL=1LL<<61,dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
typedef pair<int,int> P;
typedef pair<P,P> PP;
#define N 200001
vector<int> G[N],rG[N],g;
bool u[N];
int n,cmp[N];

void add_edge(int x,int y){G[x].push_back(y);rG[y].push_back(x);}
void dfs(int x){u[x]=1;rep(i,G[x].size())if(!u[G[x][i]])dfs(G[x][i]);g.push_back(x);} 
void rdfs(int x,int k){u[x]=1;cmp[x]=k;rep(i,rG[x].size())if(!u[rG[x][i]])rdfs(rG[x][i],k);}
int scc() {
  mem(u);g.clear();rep(i,n)if(!u[i])dfs(i);mem(u);
  int k=0;rrep(i,g.size())if(!u[g[i]])rdfs(g[i],k++);return k;
}
void init() {
  rep(i,n) G[i].clear(),rG[i].clear();
  g.clear();
}
int rev(int x) {return (x+n/2)%n;}
int two_sat(vector<P> v) {
  init();
  rep(i,v.size()) {
    add_edge(rev(v[i].F),v[i].S);
    add_edge(rev(v[i].S),v[i].F);
  }
  scc();
  rep(i,n/2) {
    if(cmp[i]==cmp[i+n/2]) return 0;
  }
  return 1;
}
void Main() {
  int m;
  cin >> n >> m;
  PP a[m];
  rep(i,m) {
    int x,y;
    string s,t,r;
    cin >> x >> s >> t >> y >> r;
    x--,y--;
    a[i]=PP(P(x,s=="left"?0:1),P(y,r=="left"?0:1));
  }
  int l=-1,r=n-1;
  while(l+1<r) {
    int mid=(l+r)/2;
    n=mid*2;
    vector<P> v;
    rep(i,m) {
      int x=a[i].F.F,y=a[i].S.F;
      if(x>mid||y>mid) continue;
      if(a[i].F.S) x=rev(x);
      if(a[i].S.S) y=rev(y);
      v.pb(P(x,y));
    }
    if(two_sat(v)) l=mid;
    else r=mid;
  }
  cout << r+1 << endl;
}

int main(){ios::sync_with_stdio(0);cin.tie(0);Main();return 0;}
accuracy: 0.125
time_ms: 10
memory_kb: 13752
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define R cin>>
#define Z class
#define ll long long
#define ln cout<<'\n'
#define in(a) insert(a)
#define pb(a) push_back(a)
#define pd(a) printf("%.10f\n",a)
#define mem(a) memset(a,0,sizeof(a))
#define all(c) (c).begin(),(c).end()
#define iter(c) __typeof((c).begin())
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;i--)
#define REP(i,m,n) for(int i=(int)(m);i<(int)(n);i++)
#define rep(i,n) REP(i,0,n)
#define tr(it,c) for(iter(c) it=(c).begin();it!=(c).end();it++)
template<Z A>void pr(A a){cout<<a;ln;}
template<Z A,Z B>void pr(A a,B b){cout<<a<<' ';pr(b);}
template<Z A,Z B,Z C>void pr(A a,B b,C c){cout<<a<<' ';pr(b,c);}
template<Z A,Z B,Z C,Z D>void pr(A a,B b,C c,D d){cout<<a<<' ';pr(b,c,d);}
template<Z A>void PR(A a,ll n){rep(i,n){if(i)cout<<' ';cout<<a[i];}ln;}
ll check(ll n,ll m,ll x,ll y){return x>=0&&x<n&&y>=0&&y<m;}
const ll MAX=1000000007,MAXL=1LL<<61,dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
typedef pair<int,int> P;
typedef pair<P,P> PP;
#define N 200001
vector<int> G[N],rG[N],g;
bool u[N];
int n,cmp[N];

void add_edge(int x,int y){G[x].push_back(y);rG[y].push_back(x);}
void dfs(int x){u[x]=1;rep(i,G[x].size())if(!u[G[x][i]])dfs(G[x][i]);g.push_back(x);} 
void rdfs(int x,int k){u[x]=1;cmp[x]=k;rep(i,rG[x].size())if(!u[rG[x][i]])rdfs(rG[x][i],k);}
int scc() {
  mem(u);g.clear();rep(i,n)if(!u[i])dfs(i);mem(u);
  int k=0;rrep(i,g.size())if(!u[g[i]])rdfs(g[i],k++);return k;
}
void init() {
  rep(i,n) G[i].clear(),rG[i].clear();
  g.clear();
}
int rev(int x) {return (x+n/2)%n;}
int two_sat(vector<P> v) {
  init();
  rep(i,v.size()) {
    add_edge(rev(v[i].F),v[i].S);
    add_edge(rev(v[i].S),v[i].F);
  }
  scc();
  rep(i,n/2) {
    if(cmp[i]==cmp[i+n/2]) return 0;
  }
  return 1;
}
void Main() {
  int m;
  cin >> n >> m;
  PP a[m];
  rep(i,m) {
    int x,y;
    string s,t,r;
    cin >> x >> s >> t >> y >> r;
    x--,y--;
    a[i]=PP(P(x,s=="left"?0:1),P(y,r=="left"?0:1));
  }
  int l=-1,r=n+1;
  while(l+1<r) {
    int mid=(l+r)/2;
    n=mid*2;
    vector<P> v;
    rep(i,m) {
      int x=a[i].F.F,y=a[i].S.F;
      if(x>mid||y>mid) continue;
      if(a[i].F.S) x=rev(x);
      if(a[i].S.S) y=rev(y);
      v.pb(P(x,y));
    }
    if(two_sat(v)) l=mid;
    else r=mid;
  }
  cout << r+1 << endl;
}

int main(){ios::sync_with_stdio(0);cin.tie(0);Main();return 0;}
accuracy: 0.125
time_ms: 10
memory_kb: 13880
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;

typedef pair<int,int> P;
int N,M;
vector<int> G[20002];
vector<int> rG[20002];
bool used[20002];
int cmp[20002];
vector<int> vs;

void init(int size){
  vs.clear();
  for(int i=0;i<size;i++) {
    G[i].clear();
    rG[i].clear();
    cmp[i] = -1;
    used[i] = 0;
  }
}

void add_edge(int a,int b){//a->b
  G[a].push_back( b );
  rG[b].push_back( a );
}
void dfs(int id){
  if( used[id] ) return;
  used[id] = true;
  for(int i=0;i<(int)G[id].size();i++)
    dfs(G[id][i]);
  vs.push_back( id );
}
void rdfs(int id,int k){
  if( used[id] ) return;
  used[id] = true;
  cmp[id]=k;
  for(int i=0;i<(int)rG[id].size();i++)
    rdfs(rG[id][i],k);  
}

int scc(int size){
  memset(used,0,sizeof(used));
  for(int i=0;i<size;i++)
    dfs(i);
  memset(used,0,sizeof(used));
  int k=0;
  for(int i=(int)vs.size()-1;i>-1;i--){
    if( used[vs[i]] ) continue;
    rdfs(vs[i],k++);
  }  
  return k;
}

int rev(int a){
  if( a & 1 ) return --a;
  else return ++a;
}

void view(int size){
  for(int i=0;i<size;i++){
    if( G[i].empty() ) continue;
    cout << i << endl;
    for(int j=0;j<(int)G[i].size();j++){
      cout << " -> " << G[i][j] << endl;
    }
  }
}

//?????????a,~a,b,~b,c,~c...,?????????0,1,2,3,4,5...??¨????????????
bool two_SAT(const vector<P>& v,int size){
  // cout << "2-sat :" << size << endl;
  init( size );
  for(int i=0;i<(int)v.size();i++){
    //cout << v[i].first << " V " << v[i].second << endl;
    //aVb
    add_edge( rev(v[i].first), v[i].second );//~a->b
    add_edge( rev(v[i].second), v[i].first );//~b->a
  }
  //  view(size);
  scc(size);
  //x??¨~x?????°???????????£?????????????????????????????????
  for(int i=0;i<size;i+=2){
    //cout << i << " " << cmp[i] << ", " << cmp[i+1] << endl;
    if( cmp[i] == cmp[i+1] ) return false;
  }
  return true;
}

vector<int> V[20001];
int main(){
  
  while(cin >> N  >> M){
    for(int i=0;i<M;i++){
      int num1,num2;
      string d1,d2,bf;
      cin >> num1 >> d1 >> bf >> num2 >> d2;
      if( num1 > num2 ){
	swap(num1,num2);
	swap(d1,d2);
      }
      int a = 2*num1, b = 2*num2;
      if( d1 == "left" ) a++;
      if( d2 == "right" ) b++;
      V[a].push_back( b );      
    }
    for(int i=2;i<2*N;i++){
      V[i].push_back(i);
      sort(V[i].begin(),V[i].end());
      V[i].erase(unique(V[i].begin(),V[i].end()),V[i].end());
    }
    int st = 1, ed = N;
    int res = 1;
    while( st <= ed ){
      int h = (st+ed)/2;
      vector<P> nv;
      for(int i=2;i<2*h;i+=2){
	int n = (int)V[i].size(), m = (int)V[i+1].size();
      int x,y;
      for(x=0;x<n;x++)
	if( V[i][x] >= 2*h ) break;
      for(y=0;y<m;y++)
	if( V[i+1][y] >= 2*h ) break;
      for(int j=0;j<x;j++)
	for(int k=0;k<y;k++)
	  nv.push_back(P(V[i][j],V[i+1][k]));	      
      }
      if( two_SAT(nv,h*2) ){
	res = max( res, h );
	st = h + 1;
      } else {
	ed = h - 1;
      }
    }
    cout << res << endl;
    for(int i=0;i<2*N;i++) V[i].clear();
  }
}
accuracy: 1
time_ms: 80
memory_kb: 4724
final_rank: 2