Problem:
Problem D
Wall Clocks
You are the manager of a chocolate sales team. Your team customarily takes tea breaks every two hours, during which varieties of new chocolate products of your company are served. Everyone looks forward to the tea breaks so much that they frequently give a glance at a wall clock.
Recently, your team has moved to a new office. You have just arranged desks in the office. One team member asked you to hang a clock on the wall in front of her desk so that she will not be late for tea breaks. Naturally, everyone seconded her.
You decided to provide an enough number of clocks to be hung in the field of view of everyone. Your team members will be satisfied if they have at least one clock (regardless of the orientation of the clock) in their view, or, more precisely, within 45 degrees left and 45 degrees right (both ends inclusive) from the facing directions of their seats. In order to buy as few clocks as possible, you should write a program that calculates the minimum number of clocks needed to
meet everyone's demand.
The office room is rectangular aligned to north-south and east-west directions. As the walls are tall enough, you can hang clocks even above the door and can assume one's eyesight is not blocked by other members or furniture. You can also assume that each clock is a point (of size zero), and so you can hang a clock even on a corner of the room.
For example, assume that there are two members. If they are sitting facing each other at positions shown in Figure D.1(A), you need to provide two clocks as they see distinct sections of the wall. If their seats are arranged as shown in Figure D.1(B), their fields of view have a common point on the wall. Thus, you can meet their demands by hanging a single clock at the point. In Figure D.1(C), their fields of view have a common wall section. You can meet their demands with a single clock by hanging it anywhere in the section. Arrangements (A), (B), and (C) in Figure D.1 correspond to Sample Input 1, 2, and 3, respectively.
Input
The input consists of a single test case, formatted as follows.
$n$ $w$ $d$
$x_1$ $y_1$ $f_1$
...
$x_n$ $y_n$ $f_n$
Figure D.1. Arrangements of seats and clocks. Gray area indicates field of view.
All numbers in the test case are integers. The first line contains the number of team members $n$ $(1 \leq n \leq 1,000)$ and the size of the office room $w$ and $d$ $(2 \leq w, d \leq 100,000)$. The office room has its width $w$ east-west, and depth $d$ north-south. Each of the following $n$ lines indicates the position and the orientation of the seat of a team member. Each member has a seat at a distinct position $(x_i, y_i)$ facing the direction $f_i$, for $i = 1, ..., n$. Here $1 \leq x_i \leq w - 1, 1 \leq y_i \leq d - 1$, and $f_i$ is one of
N
,
E
,
W
, and
S
, meaning north, east, west, and south, respectively. The position $(x, y)$ means $x$ distant from the west wall and $y$ distant from the south wall.
Output
Print the minimum number of clocks needed
...(truncated)

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define vi vector<int>
#define vl vector<ll>
#define ov4(a, b, c, d, name, ...) name
#define rep3(i, a, b, c) for(ll i = (a); i < (b); i += (c))
#define rep2(i, a, b) rep3(i, a, b, 1)
#define rep1(i, n) rep2(i, 0, n)
#define rep0(n) rep1(aaaaa, n)
#define rep(...) ov4(__VA_ARGS__, rep3, rep2, rep1, rep0)(__VA_ARGS__)
#define per(i, a, b) for(ll i = (a)-1; i >= (b); i--)
#define fore(e, v) for(auto&& e : v)
#define all(a) begin(a), end(a)
#define si(a) (int)(size(a))
#define lb(v, x) (lower_bound(all(v), x) - begin(v))
#define eb emplace_back

template<typename T, typename S> bool chmin(T& a, const S& b) { return a > b ? a = b, 1 : 0; }
template<typename T, typename S> bool chmax(T& a, const S& b) { return a < b ? a = b, 1 : 0; }

const int INF = 1e9 + 100;
const ll INFL = 3e18 + 100;

#define i128 __int128_t

struct _ {
    _() { cin.tie(0)->sync_with_stdio(0), cout.tie(0); }
} __;

#include <atcoder/all>
using namespace atcoder;
using mint93 = modint998244353;

using TUP = tuple<ll, ll, char>;
ll n, w, d;
pll f_sub1(ll x, ll y, ll dir) {
  if (dir == 0) {
    ll mn = min(x, y);
    return {x - mn, y - mn};
  }
  if (dir & 1) {
    auto [x_res, y_res] = f_sub1(w - x, y, dir ^ 1);
    return {w - x_res, y_res};
  }
  if (dir & 2) {
    auto [x_res, y_res] = f_sub1(x, d - y, dir ^ 2);
    return {x_res, d - y_res};
  }
  return {-1, -1};
}
ll f_sub2(ll x, ll y, ll dir) {
  auto [x_res, y_res] = f_sub1(x, y, dir);
  // cout << x << " " << y << " " << dir << " " << x_res << " " << y_res << "\n";
  if (x_res == 0) return y_res;
  if (y_res == d) return d + x_res;
  if (x_res == w) return w + 2 * d - y_res;
  return 2 * (w + d) - x_res;
}
pll f(TUP args) {
  auto [x, y, c] = args;
  if (c == 'S')
    return pll{f_sub2(x, y, 1), f_sub2(x, y, 0)};
  if (c == 'W')
    return pll{f_sub2(x, y, 0), f_sub2(x, y, 2)};
  if (c == 'N')
    return pll{f_sub2(x, y, 2), f_sub2(x, y, 3)};
  if (c == 'E')
    return pll{f_sub2(x, y, 3), f_sub2(x, y, 1)};
  return {-1, -1};
}
ll g(const vector<pll>& lr, ll pos) {
  ll ret = 1;
  vector<pll> lr2;
  for (auto [l, r] : lr) {
    l -= pos, r -= pos;
    if (l < 0) l += 2 * (w + d);
    if (r < 0) r += 2 * (w + d);
    if (r < l) continue;
    lr2.eb(l, r);
  }
  sort(all(lr2), [](pll a, pll b) {return a.second < b.second;});

  // cout << "pos: " << pos << "\n";
  // for (auto [l, r]: lr2) {
  //   cout << l << " " << r << "\n";
  // }

  ll mx_r = 0;
  for (auto [l, r] : lr2) {
    if (mx_r < l) {
      ret++;
      mx_r = r;
    }
  }

  return ret;
}
void solve() {
  cin >> n >> w >> d;
  vector<TUP> xyc(n);
  rep(i, n) {
    ll x, y; char c;
    cin >> x >> y >> c;
    xyc[i] = TUP{x, y, c};
  }
  vector<pll> lr(n);
  rep(i, n) {
    lr[i] = f(xyc[i]);
  }
  ll ans = n;
  for (auto [l, r] : lr) {
    ans = min(ans, g(lr, r));
  }
  cout << ans << "\n";
}
int main() {
  ll T = 1;
  // cin >> T;
  while (T--) {solve();}
}
accuracy: 1
time_ms: 20
memory_kb: 3712
final_rank: 14

code_snippet: #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define F(a,b,c)for(int a=b;a<=c;a++)
#define M(a,b)memset(a,b,sizeof(a))
#define pw(x) ((x)*(x))
#define lowbit(x) (x)&(-x)
using namespace std;
struct Q
{
	int x,y,lx,ly,rx,ry;
	char f;
}p[1002];
struct P
{
	int lp,rp;
}h[1002],t;
int totlen,res,n,w,d,size,temp;
inline bool cmp(P a,P b)
{
	return a.rp<b.rp;
}
int getdis(int x,int y,int xx,int yy)
{
	if(x==0)
	{
		if(xx==0){if(y<=yy)return yy-y;else return totlen-y+yy;}
		else if(yy==d)return d-y+xx;
		else if(xx==w)return d-y+w+d-yy;
		else return d-y+w+d+w-xx;
	}
	else if(y==d)
	{
		if(xx==0)return w-x+d+w+yy;
		else if(yy==d){if(x<=xx)return xx-x;else return totlen-x+xx;}
		else if(xx==w)return w-x+d-yy;
		else return w-x+d+w-xx;
	}
	else if(x==w)
	{
		if(xx==0)return w+y+yy;
		else if(yy==d)return w+y+d+xx;
		else if(xx==w){if(y>=yy)return y-yy;else return totlen-yy+y;}
		else return y+w-xx;
	}
	else
	{
		if(xx==0)return x+yy;
		else if(yy==d)return x+d+xx;
		else if(xx==w)return x+d+w+d-yy;
		else {if(x>=xx)return x-xx;else return totlen-xx+x;}
	}
}
int calc(int x,int y)
{
	int ret=1,now;
	F(i,1,n)
	{
		t.lp=getdis(x,y,p[i].lx,p[i].ly);t.rp=getdis(x,y,p[i].rx,p[i].ry);
		if((t.lp>t.rp)||(t.lp==0)||(t.rp==0))continue;
		size++;h[size]=t;
	}
	sort(h+1,h+size+1,cmp);
	while(size)
	{
		ret++;
		now=h[1].rp;temp=0;
		F(i,2,size)now=min(now,h[i].rp);
		F(i,1,size)if((h[i].lp>now)||(h[i].rp<now)){temp++;h[temp]=h[i];}
		size=temp;
	}
	return ret;
}
int main()
{
	scanf("%d %d %d",&n,&w,&d);res=1015;totlen=w*2+d*2;
	F(i,1,n)scanf("%d %d %c",&p[i].x,&p[i].y,&p[i].f);
	F(i,1,n)
	{
		if(p[i].f=='E')
		{
			temp=min(w-p[i].x,d-p[i].y);p[i].lx=p[i].x+temp;p[i].ly=p[i].y+temp;
			temp=min(w-p[i].x,p[i].y);  p[i].rx=p[i].x+temp;p[i].ry=p[i].y-temp;
		}
		if(p[i].f=='W')
		{
			temp=min(p[i].x,p[i].y);    p[i].lx=p[i].x-temp;p[i].ly=p[i].y-temp;
			temp=min(p[i].x,d-p[i].y);  p[i].rx=p[i].x-temp;p[i].ry=p[i].y+temp;
		}
		if(p[i].f=='N')
		{
			temp=min(p[i].x,d-p[i].y);  p[i].lx=p[i].x-temp;p[i].ly=p[i].y+temp;
			temp=min(w-p[i].x,d-p[i].y);p[i].rx=p[i].x+temp;p[i].ry=p[i].y+temp;
		}
		if(p[i].f=='S')
		{
			temp=min(w-p[i].x,p[i].y);  p[i].lx=p[i].x+temp;p[i].ly=p[i].y-temp;
			temp=min(p[i].x,p[i].y);    p[i].rx=p[i].x-temp;p[i].ry=p[i].y-temp;
		}
	}
	//F(i,1,n)printf("%d %d %d %d\n",p[i].lx,p[i].ly,p[i].rx,p[i].ry);
	F(i,1,n)
	{
		res=min(res,calc(p[i].lx,p[i].ly));
		res=min(res,calc(p[i].rx,p[i].ry));
	}
	printf("%d\n",res);
	return 0;
}
accuracy: 1
time_ms: 530
memory_kb: 3604
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int INF = 1e9 + 10;
const ll INFL = 4e18;

int main() {
    int N, W, H;
    cin >> N >> W >> H;
    vector<tuple<int, int, char>> XYF(N);
    for (auto& [x, y, f] : XYF) cin >> x >> y >> f, y = H - y;

    // 視野の区間の求める
    // 左上:0
    vector<pair<int, int>> point(N);
    vector<int> vals;
    int M = H * 2 + W * 2;
    for (int i = 0; i < N; i++) {
        auto [x, y, f] = XYF[i];

        if (f == 'N') {
            int d = y;
            int lx = (x - d + M) % M, rx = (x + d) % M;
            point[i] = {lx, rx};
        } else if (f == 'E') {
            int d = W - x;
            int ly = (W + y - d + M) % M, ry = (W + y + d) % M;
            point[i] = {ly, ry};
        } else if (f == 'S') {
            int d = H - y;
            int lx = (W + H + W - x - d + M) % M, rx = (W + H + W - x + d) % M;
            point[i] = {lx, rx};
        } else {
            int d = x;
            int ly = (W + H + W + H - y - d + M) % M, ry = (W + H + W + H - y + d) % M;
            point[i] = {ly, ry};
        }
        vals.push_back(point[i].first);
        vals.push_back(point[i].second);
    }
    sort(vals.begin(), vals.end());
    vals.erase(unique(vals.begin(), vals.end()), vals.end());
    auto Get = [&](int x) { return lower_bound(vals.begin(), vals.end(), x) - vals.begin(); };
    int V = vals.size();

    for (auto& [l, r] : point) l = Get(l), r = Get(r);
    // for(auto[l,r]:point)printf("{%d,%d}\n",l,r);

    int ans = INF;

    // 点を固定してDP
    for (int t = 0; t < V; t++) {
        // 被っている点を除く
        vector<pair<int, int>> npoint;
        for (auto [l, r] : point) {
            if (l <= r) {
                if (l <= t && t <= r)
                    continue;
                else
                    npoint.push_back({l, r});
            } else {
                if (l <= t || t <= r)
                    continue;
                else
                    npoint.push_back({l, r});
            }
        }
        swap(point, npoint);

        auto Convert = [&](int x) {
            if (x >= t) return x - t;
            return V + x - t;
        };

        // tを0にする
        for (auto& [l, r] : point) {
            l = Convert(l), r = Convert(r);
            assert(l <= r);
        }

        /*cout<<t<<endl;
        for(auto[l,r]:point){
            cout<<l<<' '<<r<<endl;
        }
        cout<<endl;*/

        /*vector<int>left(V,-1);
        for(auto[l,r]:point)left[r]=max(left[r],l);

        vector<int>dp(V+1,INF);
        dp[0]=0;
        for(int i=0;i<V;i++){
            if(left[i]==-1)dp[i+1]=dp[i];
            else dp[i+1]=dp[left[i]]+1;
        }

        ans=min(ans,dp.back()+1);*/

        sort(point.begin(), point.end(), [&](auto l, auto r) {
            if (l.second != r.second) return l.second < r.second;
            return l.first < r.first;
        });

        int right = -1;
        int res = 0;
        for (auto [l, r] : point) {
            if (l > right || r < right) {
                res++;
                right = r;
            }
        }

        ans = min(ans, res + 1);
        swap(point, npoint);
    }

    cout << ans << endl;
}
accuracy: 1
time_ms: 60
memory_kb: 3524
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll=long long;
int n;
ll w,d;
ll as_id(ll x,ll y){
  if(y==0){
    return x;
  }else if(x==w){
    return w+y;
  }else if(y==d){
    return w+d+(w-x);
  }else{
    return w+d+w+(d-y);
  }
}
int main(){
  cin.tie(0)->sync_with_stdio(0);
  vector<tuple<ll,ll,ll>>rect;
  cin>>n>>w>>d;
  rect.emplace_back(0,1,0);
  rect.emplace_back(1,0,w);
  rect.emplace_back(0,1,d);
  rect.emplace_back(1,0,0);
  vector<int>lx(n),ly(n),rx(n),ry(n);
  for(int i=0;i<n;++i){
    int x,y;cin>>x>>y;
    vector<tuple<ll,ll,ll>>lines;
    lines.emplace_back(-1,1,-x+y);
    lines.emplace_back(1,1,x+y);
    vector ix(2,vector<ll>(4)),iy(2,vector<ll>(4));
    for(int j=0;j<2;++j)for(int k=0;k<4;++k){
      auto[a0,b0,c0]=lines[j];
      auto[a1,b1,c1]=rect[k];
      ix[j][k]=(b1*c0-b0*c1)/(a0*b1-a1*b0);
      iy[j][k]=(c0*a1-c1*a0)/(a1*b0-a0*b1);
      //cout<<ix[j][k]<<','<<iy[j][k]<<endl;
    }
    char f;cin>>f;
    if(f=='N'){
      if(iy[0][1]<=d){
        lx[i]=w,ly[i]=iy[0][1];
      }else{
        lx[i]=ix[0][2],ly[i]=d;
      }
      if(0<=ix[1][2]){
        rx[i]=ix[1][2],ry[i]=d;
      }else{
        rx[i]=0,ry[i]=iy[1][3];
      }
    }else if(f=='E'){
      if(ix[1][0]<=w){
        lx[i]=ix[1][0],ly[i]=0;
      }else{
        lx[i]=w,ly[i]=iy[1][1];
      }
      if(iy[0][1]<=d){
        rx[i]=w,ry[i]=iy[0][1];
      }else{
        rx[i]=ix[0][2],ry[i]=d;
      }
    }else if(f=='W'){
      if(0<=ix[1][2]){
        lx[i]=ix[1][2],ly[i]=d;
      }else{
        lx[i]=0,ly[i]=iy[1][3];
      }
      if(0<=iy[0][3]){
        rx[i]=0,ry[i]=iy[0][3];
      }else{
        rx[i]=ix[0][0],ry[i]=0;
      }
    }else{
      if(0<=iy[0][3]){
        lx[i]=0,ly[i]=iy[0][3];
      }else{
        lx[i]=ix[0][0],ly[i]=0;
      }
      if(ix[1][0]<=w){
        rx[i]=ix[1][0],ry[i]=0;
      }else{
        rx[i]=w,ry[i]=iy[1][1];
      }
    }
  }
  /*
  for(int i=0;i<n;++i){
    cout<<lx[i]<<' '<<ly[i]<<' '<<rx[i]<<' '<<ry[i]<<'\n';
  }
  */
  ll peri=2*w+2*d;
  vector<ll>l(n),r(n);
  for(int i=0;i<n;++i){
    l[i]=as_id(lx[i],ly[i]);
    r[i]=as_id(rx[i],ry[i]);
    if(l[i]>r[i]){
      r[i]+=peri;
    }
    //cout<<l[i]<<' '<<r[i]<<'\n';
  }
  vector<ll>origins(2*n);
  for(int i=0;i<n;++i){
    origins[2*i]=l[i];
    origins[2*i+1]=r[i];
    if(peri<=origins[2*i+1])origins[2*i+1]-=peri;
  }
  int ans=1<<30;
  for(ll s:origins){
    int cnt=1;
    vector<pair<ll,ll>>rl;
    for(int i=0;i<n;++i){
      if(l[i]<=s&&s<=r[i])continue;
      if(l[i]-peri<=s&&s<=r[i]-peri)continue;
      if(s<=l[i]){
        rl.emplace_back(r[i],l[i]);
      }else{
        rl.emplace_back(r[i]+peri,l[i]+peri);
      }
    }
    sort(rl.begin(),rl.end());
    ll cur=-1<<30;
    int i=0;
    while(i<(int)rl.size()){
      auto[y,x]=rl[i];
      if(x<=cur&&cur<=y){
        ++i;
        continue;
      }
      cur=y;
      ++cnt;
      ++i;
    }
    ans=min(ans,cnt);
  }
  cout<<ans<<endl;
}
accuracy: 1
time_ms: 60
memory_kb: 3584
final_rank: 12

code_snippet: #include <bits/stdc++.h>
#define y0 y01234
#define y1 y1234
using namespace std;
int n;int w;int d;
int x;int y;char f;
vector<array<int,2>>s;
vector<array<int,2>>t;
vector<int>a;
int res=2000;
int r;
bool cp(array<int,2>i,array<int,2>j){
  return i[1]<j[1];
}
int main(){
  cin.tie(0)->sync_with_stdio(0);
  cin>>n>>w>>d;
  s.resize(n);
  // geo part
  for(int i=0;i<n;i++){
    cin>>x>>y>>f;
    switch (f){
    case 'N':
      if(y+(w-x)<=d){
	s[i][0]=w+y+(w-x);
      }else{
	s[i][0]=2*w+d-(x+(d-y));
      }
      if(y+x<=d){
	s[i][1]=2*w+2*d-(y+x);
      }else{
	s[i][1]=2*w+d-x+d-y;
      }
      break;
    case 'S':
      if(x-y<0){
	s[i][0]=2*w+2*d-(y-x);
      }else{
	s[i][0]=x-y;
      }
      if(x+y<=w){
	s[i][1]=x+y;
      }else{
	s[i][1]=w+y-(w-x);
      }
      break;
    case 'W':
      if(y+x<=d){
	s[i][0]=2*w+2*d-(y+x);
      }else{
	s[i][0]=2*w+d-x+d-y;
      }
      if(x-y<0){
	s[i][1]=2*w+2*d-(y-x);
      }else{
	s[i][1]=x-y;
      }
      break;
    case 'E':
      if(x+y<=w){
	s[i][0]=x+y;
      }else{
	s[i][0]=w+y-(w-x);
      }
      if(y+(w-x)<=d){
	s[i][1]=w+y+(w-x);
      }else{
	s[i][1]=2*w+d-(x+(d-y));
      }
      break;
    }
  }
  // dp part
  a.resize(2*n);
  for(int i=0;i<n;i++){
    a[2*i]=s[i][0];
    a[2*i+1]=s[i][1];
  }
  sort(a.begin(),a.end());
  a.erase(unique(a.begin(),a.end()),a.end());
  t.reserve(n);
  for(int i:a){
    r=1;
    for(auto j:s){
      if((j[0]<=i&&i<=j[1])||(j[1]<=j[0]&&(i<=j[1]||j[0]<=i))){
	;
      }else{
	t.push_back({
	    j[0]<=i?j[0]+2*d+2*w:j[0],
	    j[1]<=i?j[1]+2*d+2*w:j[1]
	  });
      }
    }
    sort(t.begin(),t.end(),cp);
    int pos=-1;
    for(auto j:t){
      if(pos<j[0]){
	r++;
	pos=j[1];
      }
    }
    if(r<res)res=r;
    t.clear();
  }
  cout<<res<<'\n';
}
accuracy: 1
time_ms: 50
memory_kb: 3584
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define srep(i, s, t) for(int i = (s); i < (t); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
using i64 = long long;
using f64 = long double;
i64 floor_div(const i64 n, const i64 d) { assert(d != 0); return n / d - static_cast<i64>((n ^ d) <  0 && n % d != 0); }
i64  ceil_div(const i64 n, const i64 d) { assert(d != 0); return n / d + static_cast<i64>((n ^ d) >= 0 && n % d != 0); }

int main() {
    cin.tie(0)->sync_with_stdio(0);
    
    int n, w, h; cin >> n >> w >> h;
    vector<pair<int, int>> a;
    rep(i, n) {
        int x, y; char f; cin >> x >> y >> f;
        int o = 0;
        if(f == 'S') a.push_back({o + x - y, o + x + y});
        o += w;
        if(f == 'E') a.push_back({o + y - (w - x), o + y + (w - x)});
        o += h;
        if(f == 'N') a.push_back({o + (w - x) - (h - y), o + (w - x) + (h - y)});
        o += w;
        if(f == 'W') a.push_back({o + (h - y) - x, o + (h - y) + x});
        o += h;
    }

    const int S = 2 * (h + w);
    auto F = [&](int p) -> int {
        vector<pair<int, int>> b;
        for(auto [L, R] : a) {
            bool co = [&] {
                for(int d : {-1, 0, +1}) if(L <= p - d * S and p - d * S <= R) return true;
                return false;
            }();
            if(co) continue;
            while(R < p) L += S, R += S;
            while(p < L - S) L -= S, R -= S;
            b.push_back({L, R});
        }
        sort(b.begin(), b.end(), [&](auto I, auto J) {
            if(I.second != J.second) return I.second < J.second;
            return I.first < J.first;
        });
        int ans = 1;
        int prv = -1e9;
        for(auto [L, R] : b) {
            if(L <= prv and prv <= R) continue;
            prv = R;
            ans++;
        }
        return ans;
    };

    int ans = n;
    for(auto [L, R] : a) {
        chmin(ans, F(L));
        chmin(ans, F(R));
    }
    cout << ans << "\n";
}
accuracy: 1
time_ms: 70
memory_kb: 3524
final_rank: 10

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int Solve(vector<pair<int,int>> P) {
    if (P.empty()) return 0;
    int N = P.size();
    vector<int> ord(N);
    iota(ALL(ord),0);
    sort(ALL(ord),[&](int i, int j){return P[i].second < P[j].second;});
    int Ret = 0;
    int Cur = -inf;
    for (int i : ord) {
        if (Cur < P[i].first) Ret++, Cur = P[i].second;
    }
    return Ret;
}

int main() {
    int N, M, K, Len;
    cin >> K >> N >> M;
    Len = (N+M)*2;
    auto encode = [&](pair<int,int> P) -> int {
        if (P.second == 0) return P.first;
        if (P.first == N) return N + P.second;
        if (P.second == M) return N*2+M - P.first;
        return N*2+M*2 - P.second;
    };
    auto findpoint = [&](int X, int Y, int dir) -> int {
        if (dir == 0) {
            if (X+Y <= N) return encode({X+Y,0});
            else return encode({N,X+Y-N});
        }
        else if (dir == 1) {
            if (X+M-Y <= N) return encode({X+M-Y,M});
            else return encode({N,N+Y-X});
        }
        else if (dir == 2) {
            if (X+Y-M >= 0) return encode({X+Y-M,M});
            else return encode({0,X+Y});
        }
        else {
            if (X-Y >= 0) return encode({X-Y,0});
            else return encode({0,Y-X});
        }
    };
    vector<int> L(K), R(K), XS;
    rep(i,0,K) {
        int X, Y;
        char C;
        cin >> X >> Y >> C;
        int dir;
        if (C == 'E') dir = 0;
        if (C == 'N') dir = 1;
        if (C == 'W') dir = 2;
        if (C == 'S') dir = 3;
        L[i] = findpoint(X,Y,dir), R[i] = findpoint(X,Y,(dir+1)%4);
        XS.push_back(L[i]), XS.push_back(R[i]);
    }
    UNIQUE(XS);
    auto inside = [&](int Left, int Right, int Mid) -> bool {
        if (Left <= Right) return Left <= Mid && Mid <= Right;
        else return Mid <= Right || Left <= Mid;
    };
    int ANS = inf;
    for (int X : XS) {
        vector<pair<int,int>> P;
        rep(i,0,K) {
            if (inside(L[i],R[i],X)) continue;
            int Left = L[i], Right = R[i];
            while(Left < X) Left += Len;
            while(Right < Left) Right += Len;
            P.push_back({Left,Right});
        }
        chmin(ANS,1+Solve(P));
    }
    cout << ANS << endl;
}
accuracy: 1
time_ms: 50
memory_kb: 3476
final_rank: 5

code_snippet: #include<bits/stdc++.h>

using namespace std;

#define rep(i, n) for(int i = 0; i < (n); i++)
#define per(i, n) for(int i = (n)-1; i >= 0; i--)
#define rep2(i, l, r) for(int i = (l); i < (r); i++)
#define per2(i, l, r) for(int i = (r)-1; i >= (l); i--)
#define each(e, x) for(auto &e : x)
#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define eb emplace_back
#define MM << ' ' <<
#define TT template<typename T>
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

TT bool chmin(T &x, T y) { return x > y ? (x = y, true) : false; }

TT bool chmax(T &x, T y) { return x < y ? (x = y, true) : false; }

TT using minheap = priority_queue<T, vector<T>, greater<T>>;
TT using maxheap = priority_queue<T>;

TT void print(vector<T> v, T x = 0) {
    int n = sz(v);
    rep(i, n) cout << v[i] + x << (i == n - 1 ? '\n' : ' ');
    if (n == 0) cout << '\n';
}

TT void printn(vector<T> v, T x = 0) {
    int n = sz(v);
    rep(i, n) cout << v[i] + x << '\n';
}

TT void rearrange(vector<T> &v) {
    sort(all(v));
    v.erase(unique(all(v)), end(v));
}

TT int lb(vector<T> &v, T x) { return lower_bound(all(v), x) - begin(v); }

TT int ub(vector<T> &v, T x) { return upper_bound(all(v), x) - begin(v); }

const int inf = (1 << 30) - 1;
const ll INF = (1LL << 60) - 1;

struct io_setup {
    io_setup() {
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        cout << fixed << setprecision(15);
    }
} io_setup;

int main() {
    int n, w, h;
    cin >> n >> w >> h;
    vector<int> x(n), y(n);
    vector<char> dir(n);
    rep(i, n) cin >> x[i] >> y[i] >> dir[i];
    vector<int> l(n), r(n);
    int L = (h + w) * 2;
    rep(i, n) {
        if (dir[i] == 'W') {
            l[i] = (x[i] + y[i] > h ? L - (x[i] + y[i] - h) : h - x[i] - y[i]);
            r[i] = x[i] - y[i] + h;
        }
        else if (dir[i] == 'S') {
            l[i] = x[i] - y[i] + h;
            r[i] = x[i] + y[i] + h;
        }
        else if (dir[i] == 'E') {
            l[i] = x[i] + y[i] + h;
            r[i] = y[i] - x[i] + h + w * 2;
        }
        else if (dir[i] == 'N') {
            l[i] = y[i] - x[i] + h + w * 2;
            r[i] = (x[i] + y[i] > h ? L - (x[i] + y[i] - h) : h - x[i] - y[i]);
        }
    }
    int ans = 1e9;
    rep(t, n) {
        int p = r[t];
        vector<pii> v;
        rep(i, n) {
            if (l[i] <= p && p <= r[i] || r[i] < l[i] && l[i] <= p || p <= r[i] && r[i] < l[i]) continue;
            v.eb((L + r[i] - p) % L, (L + l[i] - p) % L);
        }
        sort(all(v));
        int val = 1, memo = 0;
        for (auto [nr, nl] : v) {
            if (nl <= memo)
                continue;
            memo = nr;
            val++;
        }
        chmin(ans, val);
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 3488
final_rank: 4

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

#define rep(i, N) for(ll i = 0; i < (ll)(N); i++)
#define fi first
#define se second
#define mkpr make_pair

using ll = long long;
using Pair = pair<ll, ll>;
using Tpl = tuple<ll, ll, ll>;

const ll LINF = 1001001001001001001ll;

ll N, W, D;

ll ff(Pair p){
    ll res;
    if(p.fi == 0) res = p.se;
    else if(p.se == D) res = p.fi + D;
    else if(p.fi == W) res = D - p.se + D + W;
    else res = W - p.fi + D + W + D;
    return res;
}

ll func1(ll x, ll y, ll f){
    Pair p;
    if(f == 0){
        ll sq = min(x, D - y);
        p = mkpr(x - sq, y + sq);
    }
    if(f == 1){
        ll sq = min(W - x, D - y);
        p = mkpr(x + sq, y + sq);
    }
    if(f == 2){
        ll sq = min(W - x, y);
        p = mkpr(x + sq, y - sq);
    }
    if(f == 3){
        ll sq = min(x, y);
        p = mkpr(x - sq, y - sq);
    }
    return ff(p) % ((D + W) * 2);
}
ll func2(ll x, ll y, ll f){
    return (func1(x, y, (f - 1 + 4) % 4)) % ((D + W) * 2);
}

int main(){
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);

    cin >> N >> W >> D;
    vector<Pair> P;
    map<char, int> mp;
    mp['W'] = 0, mp['N'] = 1, mp['E'] = 2, mp['S'] = 3;
    rep(i, N){
        int x, y; cin >> x >> y;
        char c; cin >> c;
        int f = mp[c];
        P.emplace_back(make_pair(func1(x, y, f), i + 1));
        P.emplace_back(make_pair(func2(x, y, f), -(i + 1)));
    }
    
    sort(P.begin(), P.end());

    rep(i, 0){
        cout << P[i].fi << " " << P[i].se << endl;
    }

    ll ans = LINF;
    rep(i, N * 2){
        if(P[i].se < 0) continue;
        int id = P[i].se;
        ll val = 0;
        set<ll> st;
        
        for(int j = i + 1;; j++){
            if(j >= 2 * N) j = 0;
            if(j == i) break;
            if(P[j].se < 0) st.insert(-P[j].se);
            else st.erase(P[j].se);
        }

        vector<bool> used(N + 1);
        for(int j = i, cnt = 0; cnt < 2 * N; j++, cnt++){
            if(j >= 2 * N) j = 0;
            if(P[j].se < 0) st.insert(-P[j].se);
            else if(!used[P[j].se]){
                val++;
                for(auto it : st){
                    used[it] = 1;
                }
                st.clear();
            }
        }

        ans = min(ans, val);
    }

    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 3532
final_rank: 17

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

int main() {
    int n, w, h;
    cin >> n >> w >> h;

    vector<pair<int,int>> intervals(n);

    for (int i = 0; i < n; i++) {
        int x, y;
        cin >> x >> y;

        char f;
        cin >> f;

        pair<int,int> d1, d2;

        if(f == 'N') {
            d1 = {-1,1};
            d2 = {1,1};
        }
        else if(f == 'E') {
            d1 = {1,1};
            d2 = {1,-1};
        }
        else if(f == 'W') {
            d1 = {-1,-1};
            d2 = {-1,1};
        }
        else if(f == 'S') {
            d1 = {1,-1};
            d2 = {-1,-1};
        }

        auto border = [h, w](pair<int,int> initial, pair<int,int> dir) {
            auto [x, y] = initial;
            auto [dx, dy] = dir;
            int k = (1 << 16);
            while(k) {
                int nx = x + k * dx;
                int ny = y + k * dy;

                if (0 <= nx && nx <= w && 0 <= ny && ny <= h) {
                    x = nx;
                    y = ny;
                }

                k /= 2;
            }
            return pair<int,int>{x, y};
        };

        pair<int,int> p1 = border({x, y}, d1);
        pair<int,int> p2 = border({x, y}, d2);

        auto index = [h, w](pair<int,int> p) {
            if(p.first == 0) {
                return p.second;
            }
            if(p.second == 0) {
                return 2 * h + 2 * w - p.first;
            }
            if(p.first == w) {
                return 2 * h + w - p.second;
            }
            assert(p.second == h);
            return h + p.first;
        };

        intervals[i] = {index(p1), index(p2)};
    }

    auto compressor = [n, intervals]() {
       set<int> v;
       for (int i = 0; i < n; i++) {
           v.insert(intervals[i].first);
           v.insert(intervals[i].second);
       }

       map<int,int> ret;
       int i = 0;

       for (auto x: v) {
           ret[x] = i;
           i++;
       }

       return ret;
    }();

    for (int i = 0; i < n; i++) {
        intervals[i].first = compressor[intervals[i].first];
        intervals[i].second = compressor[intervals[i].second];
    }

    int width = compressor.size();

    int ans = numeric_limits<int>::max();

    for (int start = 0; start < width; start++) {
        deque<pair<int,int>> lrs;

        for (int i = 0; i < n; i++) {
            auto [l, r] = intervals[i];
            l = (width + l - start) % width;
            r = (width + r - start) % width;

            if(l == 0 || r == 0) continue;
            if(r < l) continue;

            lrs.push_back({l, r});
        }

        sort(lrs.begin(), lrs.end(), [](pair<int,int> x, pair<int,int> y) {
            return x.second < y.second;
        });

        int cnt = 1;
        while(!lrs.empty()) {
            cnt++;
            auto f = lrs.front();
            while(!lrs.empty() && lrs.front().first <= f.second) lrs.pop_front();
        }
        ans = min(ans, cnt);
    }

    cout << ans << endl;
}
accuracy: 1
time_ms: 70
memory_kb: 3648
final_rank: 15

code_snippet: #include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

struct Seg {
  int l, r;
};

int getD(int t, int x, int y, int w, int d) { 
  if (t == 0) {
    return x + y;
  } else if (t == 1) {
    int tag = y - x + w;
    if (tag <= d) return d + w + (d - tag);
    return d + w - (tag - d);
  } else if (t == 2) {
    int tag = y + x - w;
    if (tag <= 0) return 2*d + w - tag;
    return d + w + (d - tag);
  } else {
    int tag = y - x;
    if (tag >= 0) return tag;
    return 2*d + 2*w + tag;
  }
}

int haveP(int l, int r, int d, int tot) {
  if (l <= r) return d >= l && d <= r;
  if (d < tot && d >= l) return 1;
  if (d <= r) return 1;
  return 0;
}

int cal(int u, int v, int tot) {
  if (v >= u) return v - u;
  return v - u + tot; 
}

int main() {
  int n, w, d;
  scanf("%d%d%d", &n, &w, &d);
  vector<Seg> a;
  for (int i = 0; i < n; i++) {
    int x, y;
    char s[5];
    scanf("%d%d%s", &x, &y, s);
    int l = -1, r = -1;
    if (s[0] == 'W') {
      l = getD(3, x, y, w, d);
      r = getD(0, x, y, w, d);
    }
    if (s[0] == 'E') {
      l = getD(1, x, y, w, d);
      r = getD(2, x, y, w, d);
    }
    if (s[0] == 'N') {
      l = getD(0, x, y, w, d);
      r = getD(1, x, y, w, d);
    }
    if (s[0] == 'S') {
      l = getD(2, x, y, w, d);
      r = getD(3, x, y, w, d);
    }
    a.push_back(Seg{l, r});
  }
  int tot = 2*d + 2*w;
  int ans = -1;
  for (int i = 0; i < n; i++) {
    int st = a[i].r;
    vector<Seg> b;
    for (auto cur: a) {
      if (!haveP(cur.l, cur.r, st, tot)) {
        b.push_back(Seg{cal(st, cur.l, tot), cal(st, cur.r, tot)});
      }
    }
    sort(b.begin(), b.end(), [](auto u, auto v) {
      return u.r < v.r;
    });
    int lst = 0;
    int take = 1;
    for (auto cur: b) {
      if (cur.l > lst) {
        take++;
        lst = cur.r;
      }
    }
    if (ans == -1 || ans > take) ans = take;
  }
  printf("%d\n", ans);
  return 0; 
}
accuracy: 1
time_ms: 20
memory_kb: 3012
final_rank: 1

code_snippet: #include<bits/stdc++.h>
#define rep(i,a,...) for(int i = (a)*(strlen(#__VA_ARGS__)!=0);i<(int)(strlen(#__VA_ARGS__)?__VA_ARGS__:(a));++i)
#define per(i,a,...) for(int i = (strlen(#__VA_ARGS__)?__VA_ARGS__:(a))-1;i>=(int)(strlen(#__VA_ARGS__)?(a):0);--i)
#define foreach(i, n) for(auto &i:(n))
#define all(x) (x).begin(), (x).end()
#define bit(x) (1ll << (x))
#define lambda(RES_TYPE, ...) (function<RES_TYPE(__VA_ARGS__)>)[&](__VA_ARGS__) -> RES_TYPE
#define method(FUNC_NAME, RES_TYPE, ...) function<RES_TYPE(__VA_ARGS__)> FUNC_NAME = lambda(RES_TYPE, __VA_ARGS__)
using namespace std;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
//const ll MOD = (ll)1e9+7;
const ll MOD = 998244353;
const int INF = (ll)1e9+7;
const ll INFLL = (ll)1e18;
template<class t>
using vvector = vector<vector<t>>;
template<class t>
using vvvector = vector<vector<vector<t>>>;
template<class t>
using priority_queuer = priority_queue<t, vector<t>, greater<t>>;
template<class t, class u> bool chmax(t &a, u b){if(a<b){a=b;return true;}return false;}
template<class t, class u> bool chmin(t &a, u b){if(a>b){a=b;return true;}return false;}
#ifdef DEBUG
#define debug(x) cout<<"LINE "<<__LINE__<<": "<<#x<<" = "<<x<<endl;
#else
#define debug(x) (void)0
#endif

namespace templates{
    ll modpow(ll x, ll b,ll mod=MOD){
        ll res = 1;
        while(b){
            if(b&1)res = res * x % mod;
            x = x * x % mod;
            b>>=1;
        }
        return res;
    }

    ll modinv(ll x){
        return modpow(x, MOD-2);
    }

    bool was_output = false;

    void print();
    template <class t> void print(const vector<t> &);
    template <class t, class u> void print(const pair<t, u> &);
    template <class t> void print(const t&);
    template <class Head, class... Tail> void print(const Head&, const Tail&...);

    template <class t> void println(const vector<vector<t>>&);
    template <class t> void println(const vector<t>&);
    template <class t> void println(const t&);
    template <class Head, class... Tail> void println(const Head&, const Tail&...);
    void println();
    void newline();

    void print(){
        return;
    }

    template <class t>
    void print(const vector<t>&x){
        for(const t&i:x)print(i);
    }
    template <class t, class u>
    void print(const pair<t,u>&p){
        print(p.first);
        print(p.second);
    }
    template <class t>
    void print(const t&x){
        if(was_output)cout<<" ";
        cout<<x;
        was_output = true;
    }
    template <class Head, class... Tail>
    void print(const Head&head,const Tail&...tail){
        print(head);
        print(tail...);
    }

    template<class t>
    void println(const vector<vector<t>>&x){
        for(vector<t> i:x)println(i);
    }
    template<class t>
    void println(const vector<t>&x){
        for(const t&i:x)print(i);
        println();
    }
    template <class t>
    void println(const t&x){
        print(x);
        println();
    }
    void println(){
        if(was_output){
            cout << endl;
            was_output = false;
        }
    }
    template <class Head, class... Tail>
    void println(const Head&head,const Tail&...tail){
        print(head);
        println(tail...);
    }

    void newline(){
        was_output = true;
        println();
    }

    template<class t>
    istream& operator>>(istream&is, vector<t>&x){
        for(auto &i:x)is >> i;
        return is;
    }

    template<class t, class u>
    istream& operator>>(istream&is, pair<t, u>&x){
        is >> x.first >> x.second;
        return is;
    }

    template<class t>
    ostream& operator<<(ostream&os, vector<t> &v){
        os << "{";
        for(t &i:v){
            os << i << ", ";
        }
        os << "}";
        return os;
    }

    template<class t = long long>
    t in(){
        t res; cin >> res; return res;
    }

    template<class t>
    vector<t> sorted(vector<t> line,function<bool(t,t)> comp=[](t a,t b){return a<b;}){
        sort(line.begin(),line.end(),comp);
        return line;
    }

    template<class t>
    vector<t> reversed(vector<t> line){
        reverse(line.begin(),line.end());
        return line;
    }
    string reversed(string str){
        reverse(str.begin(),str.end());
        return str;
    }

    long long gcd(long long a,long long b){
        while(b){
            a %= b;
            swap(a,b);
        }
        return a;
    }

    long long lcm(long long a,long long b){
        return a / gcd(a,b) * b;
    }

    class output_initializer{
    public:
        output_initializer(){
            ios::sync_with_stdio(false);
            cin.tie(nullptr);
            cout << setprecision(20);
        }
    };output_initializer OUTPUT_INITIALIZER_INSTANCE = output_initializer();
}

using namespace templates;

map<int,int> compress(vector<pii> line){
    map<int,int> m;
    foreach(i,line){
        m[i.first]=0;
        m[i.second]=0;
    }
    int cnt = 0;
    foreach(i,m)i.second = cnt++;
    return m;
}

int func(){
    int n = in();
    int w = in();
    int h = in();
    method(lus,int,int y,int x,int h,int w){
        if(y <= x)return x - y;
        return w * 2 + h + (h - y) + x;
    };
    method(rus,int,int y,int x,int h,int w){
        return (lus(w-x,y,w,h) + w) % (h * 2 + w * 2);
    };
    method(rds,int,int y,int x,int h,int w){
        return (rus(w-x,y,w,h) + w) % (h * 2 + w * 2);
    };
    method(lds,int,int y,int x,int h,int w){
        return (rds(w-x,y,w,h) + w) % (h * 2 + w * 2);
    };
    method(lu,int,int y,int x){
        return lus(y,x,h,w);
    };
    method(ru,int,int y,int x){
        return rus(y,x,h,w);
    };
    method(rd,int,int y,int x){
        return rds(y,x,h,w);
    };
    method(ld,int,int y,int x){
        return lds(y,x,h,w);
    };
    vector<pii> line;
    rep(_,n){
        int x = in();
        int y = h-in();
        char c = in<char>();
        if(c=='N'){
            line.emplace_back(lu(y,x),ru(y,x));
        }else if(c=='E'){
            line.emplace_back(ru(y,x),rd(y,x));
        }else if(c=='S'){
            line.emplace_back(rd(y,x),ld(y,x));
        }else if(c=='W'){
            line.emplace_back(ld(y,x),lu(y,x));
        }else{
            exit(1);
        }
    }
    map<int,int> convert = compress(line);
    foreach(i,line){
        i.first = convert[i.first];
        i.second = convert[i.second];
    }
    int per = convert.size();
    method(calc,int,vector<pii> line){
        method(f,int,int start){
            vvector<int> ends(per);
            vvector<int> starts(per);
            vector<int> used(n,false);
            vector<int> has;
            int res = 0;
            rep(i,n){
                int l = line[i].first;
                int r = line[i].second;
                if(r < l)r += per;
                if(l <= start and start <= r or l <= start + per and start + per <= r){
                    has.emplace_back(i);
                    used[i] = true;
                    ends[line[i].second].emplace_back(i);
                }else{
                    starts[line[i].first].emplace_back(i);
                }
            }
            int t = start;
            do{
                foreach(s,starts[t]){
                    if(used[s])continue;
                    ends[line[s].second].emplace_back(s);
                    used[s] = true;
                    has.emplace_back(s);
                }
                bool flag = false;
                foreach(e,ends[t]){
                    if(used[e])flag = true;
                }
                if(flag){
                    foreach(p,has){
                        used[p] = false;
                    }
                    has.clear();
                    ++res;
                }
                t = (t + 1) % per;
            }while(t != start);
            if(has.size())++res;
            return res;
        };
        int res = INF;
        foreach(i,line){
            chmin(res,f(i.second));
        }
        return res;
    };
    int res = INF;
    chmin(res,calc(line));
    return res;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    println(func());
    return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 3732
final_rank: 18

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

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

  int w, h;
  cin >> w >> h;

  auto fix = [w, h](int x, int y, char f) {
    int l, r;
    // {{{
    if (f == 'N') {
      int d = y;
      l = x - d;
      r = x + d;
    }
    if (f == 'E') {
      int d = w - x;
      l = w + y - d;
      r = w + y + d;
    }
    if (f == 'S') {
      int d = h - y;
      l = (h + w + w - x) - d;
      r = (h + w + w - x) + d;
    }
    if (f == 'W') {
      int d = x;
      l = (h + h + w + w - y) - d;
      r = (h + h + w + w - y) + d;
    }

    // }}}
    // [l, r)
    return make_pair(l, r + 1);
  };

  vector< pair<int, int> > vs;
  for (int i = 0; i < n; i++) {
    int x, y;
    char f;
    cin >> x >> y >> f;
    vs.emplace_back(fix(x, h - y, f));
  }
  
  sort(vs.begin(), vs.end(), [](auto a, auto b) { return a.second < b.second; });

  vector< int > ushi;
  for (auto &[l, r] : vs) {
    ushi.emplace_back(l);
    ushi.emplace_back(r - 1);
  }

  sort(ushi.begin(), ushi.end());
  ushi.erase(unique(ushi.begin(), ushi.end()), ushi.end());

  auto cut = [h, w](const vector< pair<int, int> > &vs, int v) {
    // l < r and v < r, v ∉ [l, r)
    vector< pair<int, int> > res;
    for (auto [l, r] : vs) {
      while (r <= v) {
        l += 2 * (h + w);
        r += 2 * (h + w);
      }

      if (l <= v) continue;
      res.emplace_back(l, r);
    }

    return res;
  };

  auto solve = [](vector< pair<int, int> > vs) {
    sort(vs.begin(), vs.end(), [](auto a, auto b) { return a.second < b.second; });
    int res = 0;
    int ok = -1001001001;
    for (auto &[l, r] : vs) {
      if (ok <= l) {
        ok = r;
        res++;
      }
    }

    return res;
  };

  int ans = 1001001001;
  for (auto &v : ushi) {
    ans = min(ans, 1 + solve(cut(vs, v)));
  }

  cout << ans << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 3500
final_rank: 3

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
//using namespace atcoder;
#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
using namespace std;
 
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<int, int> pii;
typedef pair<long long, long long> PLL;
typedef pair<int, PII> TIII;
 
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
 
 
#define FOR(i, s, n) for (int i = s; i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define trav(a, x) for (auto &a : x)
#define all(x) x.begin(), x.end()
 
#define MOD 1000000007
 
template<class T1, class T2> inline bool chmax(T1 &a, T2 b) {if (a < b) {a = b; return true;} return false;}
template<class T1, class T2> inline bool chmin(T1 &a, T2 b) {if (a > b) {a = b; return true;} return false;}
const double EPS = 1e-8, PI = acos(-1);
const double pi = 3.141592653589793238462643383279;
//ここから編集    
typedef string::const_iterator State;
ll GCD(ll a, ll b){
  return (b==0)?a:GCD(b, a%b);
}
ll LCM(ll a, ll b){
  return a/GCD(a, b) * b;
}
template< int mod >
struct ModInt {
  int x;
 
  ModInt() : x(0) {}
 
  ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}
 
  ModInt &operator+=(const ModInt &p) {
    if((x += p.x) >= mod) x -= mod;
    return *this;
  }
 
  ModInt &operator-=(const ModInt &p) {
    if((x += mod - p.x) >= mod) x -= mod;
    return *this;
  }
 
  ModInt &operator*=(const ModInt &p) {
    x = (int) (1LL * x * p.x % mod);
    return *this;
  }
 
  ModInt &operator/=(const ModInt &p) {
    *this *= p.inverse();
    return *this;
  }
 
  ModInt operator-() const { return ModInt(-x); }
 
  ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; }
 
  ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; }
 
  ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; }
 
  ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; }
 
  bool operator==(const ModInt &p) const { return x == p.x; }
 
  bool operator!=(const ModInt &p) const { return x != p.x; }
 
  ModInt inverse() const {
    int a = x, b = mod, u = 1, v = 0, t;
    while(b > 0) {
      t = a / b;
      swap(a -= t * b, b);
      swap(u -= t * v, v);
    }
    return ModInt(u);
  }
 
  ModInt pow(int64_t n) const {
    ModInt ret(1), mul(x);
    while(n > 0) {
      if(n & 1) ret *= mul;
      mul *= mul;
      n >>= 1;
    }
    return ret;
  }
 
  friend ostream &operator<<(ostream &os, const ModInt &p) {
    return os << p.x;
  }
 
  friend istream &operator>>(istream &is, ModInt &a) {
    int64_t t;
    is >> t;
    a = ModInt< mod >(t);
    return (is);
  }
 
  static int get_mod() { return mod; }
};
 
using modint = ModInt< 1000000007 >;
template< typename T >
struct Combination {
  vector< T > _fact, _rfact, _inv;
 
  Combination(int sz) : _fact(sz + 1), _rfact(sz + 1), _inv(sz + 1) {
    _fact[0] = _rfact[sz] = _inv[0] = 1;
    for(int i = 1; i <= sz; i++) _fact[i] = _fact[i - 1] * i;
    _rfact[sz] /= _fact[sz];
    for(int i = sz - 1; i >= 0; i--) _rfact[i] = _rfact[i + 1] * (i + 1);
    for(int i = 1; i <= sz; i++) _inv[i] = _rfact[i] * _fact[i - 1];
  }
 
  inline T fact(int k) const { return _fact[k]; }
 
  inline T rfact(int k) const { return _rfact[k]; }
 
  inline T inv(int k) const { return _inv[k]; }
 
  T P(int n, int r) const {
    if(r < 0 || n < r) return 0;
    return fact(n) * rfact(n - r);
  }
 
  T C(int p, int q) const {
    if(q < 0 || p < q) return 0;
    return fact(p) * rfact(q) * rfact(p - q);
  }
 
  T H(int n, int r) const {
    if(n < 0 || r < 0) return (0);
    return r == 0 ? 1 : C(n + r - 1, r);
  }
};
 
ll modpow(ll x, ll n, ll mod) {
  ll res = 1;
  x %= mod;
  if(x == 0) return 0;
  while(n) {
    if(n&1) res = (res * x) % mod;
    x = (x * x) % mod;
    n >>= 1;
  }
  return res;
} 
inline long long mod(long long a, long long m) {
    return (a % m + m) % m;
}
template<typename T> 
struct BIT{
  int N;
  std::vector<T> node;
  BIT(){}
  BIT(int n){
    N = n;
    node.resize(N+10);
  }
  void build(int n) {
    N = n;
    node.resize(N+10);
  }
  /* a: 1-indexed */
  void add(int a, T x){
    for(int i=a; i<(int)node.size(); i += i & -i) node[i] += x;
  }

  /* [1, a] */
  T sum(int a){
    T res = 0;
    for(int x=a; x>0; x -= x & -x) res += node[x];
    return res;
  }

  /* [l, r] */
  T rangesum(int l, int r){
    return sum(r) - sum(l-1);
  }

  /* 
    a1+a2+...+aw >= valとなるような最小のwを返す
    @verify https://codeforces.com/contest/992/problem/E
  */
  int lower_bound(T val) {
    if(val < 0) return 0;

    int res = 0;
    int n = 1; 
    while (n < N) n *= 2;

    T tv=0;
    for (int k = n; k > 0; k /= 2) {
      if(res + k < N && node[res + k] < val){
        val -= node[res+k];
        res += k;
      }
    }
    return res+1; 
  }
};

struct UnionFind{
  std::vector<int> par;
  std::vector<int> siz;

  UnionFind(int sz_): par(sz_), siz(sz_) {
    for(int i=0; i<sz_; ++i) par[i] = i, siz[i] = 1;
  }

  void init(int sz_){
    par.resize(sz_);
    siz.resize(sz_);
    for(int i=0; i<sz_; ++i) par[i] = i, siz[i] = 1;
  }

  int root(int x){
    if(x == par[x]) return x;
    return par[x] = root(par[x]);
  }

  bool merge(int x, int y){
    x = root(x), y = root(y);
    if(x == y) return false;
    if(siz[x] < siz[y]) std::swap(x, y);
    siz[x] += siz[y];
    par[y] = x;
    return true;
  }

  bool issame(int x, int y){
    return root(x) == root(y);
  }

  int size(int x){
    return siz[root(x)];
  }
};
struct RollingHash{

    using ull = unsigned long long;
    const ull mod = (1ULL << 61) - 1;
    const ull MASK30 = (1ULL << 30) - 1;
    const ull MASK31 = (1ULL << 31) - 1;

    const ull MASK61 = mod;

    ull base;
    int n;
    vector<ull> hash, pow;

    RollingHash(const string &s)
    {
        random_device rnd;
        mt19937_64 mt(rnd());
        base = 1001;
        
        n = (int)s.size();
        hash.assign(n+1, 0);
        pow.assign(n+1, 1);
        
        for(int i=0; i<n; i++){
            hash[i+1] = calc_mod(mul(hash[i], base) + s[i]);
            pow[i+1] = calc_mod(mul(pow[i], base));
        }
    }

    ull calc_mod(ull x){
        ull xu = x >> 61;
        ull xd = x & MASK61;
        ull res = xu + xd;
        if(res >= mod) res -= mod;
        return res;
    }

    ull mul(ull a, ull b){
        ull au = a >> 31;
        ull ad = a & MASK31;
        ull bu = b >> 31;
        ull bd = b & MASK31;
        ull mid = ad * bu + au * bd;
        ull midu = mid >> 30;
        ull midd = mid & MASK30;
        return calc_mod(au * bu * 2 + midu + (midd << 31) + ad * bd);
    }

    //[l,r)のハッシュ値
    inline ull get(int l, int r){
        ull res = calc_mod(hash[r] + mod*3-mul(hash[l], pow[r-l]));
        return res;
    }
    //string tのハッシュ値
    inline ull get(string t){
        ull res = 0;
        for(int i=0; i<t.size(); i++){
            res = calc_mod(mul(res, base)+t[i]);
        }
        return res;
    }
    //string s中のtの数をカウント
    inline int count(string t) {
        if(t.size() > n) return 0;
        auto hs = get(t);
        int res = 0;
        for(int i=0; i<n-t.size()+1; i++){
            if(get(i, i+t.size()) == hs) res++; 
        }
        return res;
    }

    /* 
        concat 
        @verify https://codeforces.com/problemset/problem/514/C
    */
    inline ull concat(ull h1, ull h2, int h2len){
      return calc_mod(h2 + mul(h1, pow[h2len]));
    }

    // LCPを求める S[a:] T[b:]
    inline int LCP(int a, int b){
        int len = min((int)hash.size()-a, (int)hash.size()-b);
        
        int lb = -1, ub = len;
        while(ub-lb>1){
            int mid = (lb+ub)/2;

            if(get(a, a+mid) == get(b, b+mid)) lb = mid;
            else ub = mid;
        }
        return lb;
    }
};
using Point = complex< double >;
bool eq(double a, double b){ return fabs(a-b) < EPS; }
namespace std {
  bool operator<(const Point a, const Point b) {
    if(eq(a.real(),b.real())) return a.imag() < b.imag();
    return a.real() < b.real();
  }
}

istream &operator>> (istream &is, Point &p) {
  double a, b;
  is >> a >> b;
  p = Point(a, b);
  return is;
}

ostream &operator<< (ostream &os, Point &p) {
  return os << fixed << setprecision(10) << p.real() << " " << p.imag();
}

bool operator<(const Point &a, const Point &b) {
  return a.real() != b.real() ? a.real() < b.real() : a.imag() < b.imag();
}

// rotate Φ(rad)
// x = r * cos(θ + Φ)
//   = r * cos(θ) * cos(Φ) - r * sin(θ) * sin(Φ)
//   = x * cos(Φ) - y * sin(Φ) (∵ cos(θ) = x/r, sin(θ) = y/r)  
Point rotate(double phi, const Point &p) {
  double x = p.real(), y = p.imag();
  return Point(x * cos(phi) - y * sin(phi), x * sin(phi) + y * cos(phi));
}

double radian_to_degree(double r) {
  return (r * 180.0 / PI);
}

double degree_to_radian(double d) {
  return (d * PI / 180.0);
}

struct Line{
  Point a, b;

  Line() = default;

  Line(Point a, Point b) : a(a), b(b){}

  Line(double A, double B, double C){
    //ax + by = c
    if(eq(A, 0)){
      a = Point(0, C/B), b = Point(1, C/B);
    }else if(eq(B, 0)){
      a = Point(C/A, 0), b = Point(C/A, 1);
    }else{
      a = Point(0, C/B), b = Point(C/A, 0);
    }
  }

  friend istream &operator>>(istream &is, Line &a) {
    return is >> a.a >> a.b;
  }
  friend ostream &operator<<(ostream &os, Line &a) {
    return os << a.a << " to " << a.b;
  }
};

struct Segment: Line {
  Segment() = default;

  Segment(Point a, Point b) : Line(a, b) {}
};

struct Circle {
  Point p;
  double r;

  Circle() = default;

  Circle(Point p, double r): p(p), r(r){}
};

using Points = vector<Point>;
using Polygon = vector<Point>;
using Segments = vector<Segment>;
using Lines = vector<Line>;
using Circles = vector<Circle>;

double cross(const Point &a, const Point &b) {
  return a.real() * b.imag() - a.imag() * b.real();
}

double dot(const Point& a, const Point &b) {
  return a.real() * b.real() + a.imag() * b.imag();
}

//https://mathtrain.jp/projection
Point projection(const Line &l, const Point &p){
  double t = dot(p - l.a, l.a-l.b) / norm(l.a - l.b);
  return l.a + (l.a - l.b) * t;
}

Point projection(const Segment &l, const Point &p){
  double t = dot(p - l.a, l.b-l.a) / norm(l.a - l.b);
  return l.a + (l.b - l.a) * t;
}

Point reflection(const Line &l, const Point &p){
  return p + (projection(l, p) - p) * 2.0;
}

int ccw(const Point &a, const Point &b, const Point &c) {
  if(cross(b-a, c-a) > EPS) return 1;   // "COUNTER_CLOCKWISE"
  if(cross(b-a, c-a) < -EPS) return -1; // "CLOCKWISE"
  if(dot(b-a, c-a) < -EPS) return 2;    // "ONLINE_BACK" c-a-b
  if(norm(b-a) < norm(c-a) - EPS) return -2;  // "ONLINE_FRONT" a-b-c
  return 0;                         // "ON_SEGMENT" a-c-b
}

bool parallel(const Line &a, const Line &b){
  return eq(cross(a.a-a.b, b.a-b.b), 0.0);
}
bool orthogonal(const Line &a, const Line &b){
  return eq(dot(a.a-a.b, b.a-b.b), 0.0);
}
enum { OUT, ON, IN };

int contains(const Polygon& Q, const Point& p){
  bool in = false;
  for(int i=0; i<Q.size(); i++){
    Point a = Q[i] - p, b = Q[(i+1)%Q.size()]-p;
    if(a.imag() > b.imag()) swap(a, b);
    if(a.imag() <= 0 && 0 < b.imag() && cross(a, b) < 0) in = !in;
    if(cross(a, b) == 0 && dot(a, b) <= 0) return ON;
  }
  return in ? IN : OUT;
}
bool intersect(const Segment &s, const Point &p){
  return ccw(s.a, s.b, p) == 0;
}

//直線の交差判定
bool intersect(const Line &a, const Line &b) {
  if(parallel(a, b)) return 0;
  return 1;
}

//線分が重なる/端点で交わるときtrue
bool intersect(const Segment &a, const Segment &b) {
  return ccw(a.a, a.b, b.a) * ccw(a.a, a.b, b.b) <= 0 && ccw(b.a, b.b, a.a) * ccw(b.a, b.b, a.b) <= 0;
}
Point crosspoint(const Line &a, const Line &b){
  double d = cross(b.b-b.a, a.b-a.a);
  if(eq(d, 0.0)) return Point(1e9, 1e9); 
  
  return a.a + (a.b - a.a) * cross(b.b-b.a, b.b-a.a) / d;
}

Point crosspoint(const Segment &a, const Segment &b){
  return crosspoint(Line(a.a, a.b), Line(b.a, b.b));
}
double distance(const Point &a, const Point &b){
  return abs(a - b);
}
double distance(const Line &l, const Point &p){
  return abs( cross(p - l.a, l.b-l.a) / abs(l.b-l.a) );
}
double distance(const Segment &s, const Point &p){
  Point r = projection(s, p);
  if(intersect(s, r)) return abs(r-p);
  return min(abs(s.a - p), abs(s.b - p));
}
// double distance(const Line &a, const Line &b){

// }
// double distance(const Line &a, const Segment &b){

// }
double distance(const Segment &a, const Segment &b) {
  return intersect(a, b) ? 0 : min({distance(a, b.a), distance(a, b.b), distance(b, a.a), distance(b, a.b)});
}

/* 2円の交点 */
vector<Point> crosspointCC(Circle C1, Circle C2){
  vector<Point> ps;
  Point ab = C2.p - C1.p;
  double d = abs(ab);
  double rc = (C1.r * C1.r + d * d - C2.r * C2.r) / (2 * d);
  if(eq(d, 0) || C1.r < abs(rc)) return ps;

  double rs = sqrt(C1.r * C1.r - rc*rc);

  Point abN = ab * Point(0, rs/d);
  Point cp = C1.p + rc / d * ab;
  ps.push_back(cp + abN);
  if(!eq(norm(abN), 0))ps.push_back(cp-abN);
  return ps;
}

vector<Point> crosspointCL(Circle C, Line l){
  Point p = projection(l, C.p);

  Point e = (l.b-l.a)/abs(l.b-l.a);
  if(eq(distance(l, C.p), C.r)) {
    return vector<Point>{p, p};
  }
  double base = sqrt(C.r*C.r-norm(p-C.p));
  
  return vector<Point>{p+e*base, p-e*base};
}

/* 円同士の共通部分の面積を求める */
// verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_I date: 2020/10/11
long double AreaofCC(Circle& C1, Circle& C2){
  if(C1.r > C2.r) swap(C1, C2);
  long double nor = norm(C1.p - C2.p);
  long double dist = sqrtl(nor);
  
  if(C1.r + C2.r < dist+EPS) return 0;

  if(dist + C1.r < C2.r + EPS) return C1.r * C1.r * PI;

  long double theta1 = acosl((nor + C1.r*C1.r - C2.r * C2.r)/(2*C1.r*dist));

  long double theta2 = acosl((nor + C2.r*C2.r - C1.r * C1.r)/(2*C2.r*dist));
  
  return (theta1 - sinl(theta1+ theta1) *0.5) * C1.r * C1.r + (theta2 - sinl(theta2+theta2) *0.5) * C2.r * C2.r;
}


Polygon convex_hull(Polygon &p)
{
    int n = (int)p.size(), k = 0;
    if (n <= 2)
        return p;
    sort(p.begin(), p.end());
    vector<Point> ch(n * 2);

    for (int i = 0; i < n; ch[k++] = p[i++])
    {
        while (k >= 2 && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0)
            --k;
    }

    for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--])
    {
        while (k >= t && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0)
            --k;
    }
    ch.resize(k - 1);
    return ch;
}
double convex_diameter(const Polygon &p)
{
    int n = (int)p.size();
    if (n == 2)
        return abs(p[0] - p[1]);

    int is = 0, js = 0;
    for (int i = 1; i < n; ++i)
    {
        if (imag(p[i]) > imag(p[is]))
            is = i;
        if (imag(p[i]) < imag(p[js]))
            js = i;
    }

    double res = abs(p[is] - p[js]);
    int i, maxi, j, maxj;
    i = maxi = is;
    j = maxj = js;
    do
    {
        if (cross(p[(i + 1) % n] - p[i], p[(j + 1) % n] - p[j]) >= 0)
            j = (j + 1) % n;
        else
            i = (i + 1) % n;
        res = max(res, abs(p[i] - p[j]));
    } while (i != is || j != js);
    return res;
}

Polygon convex_cut(const Polygon &p, const Line l)
{
    Polygon ret;
    for (int i = 0; i < p.size(); ++i)
    {
        Point now = p[i], nxt = p[(i + 1) % p.size()];
        if (ccw(l.a, l.b, now) != -1) //交点が線分l上にあるとき
            ret.push_back(now);
        if (ccw(l.a, l.b, now) * ccw(l.a, l.b, nxt) < 0)
        {
            ret.push_back(crosspoint(Line(now, nxt), l));
        }
    }
    return (ret);
}
double closestpair(Points &a, int l, int r){
  if(r-l<=1) return 1e20;
  int mid = (l+r)/2;

  double X = a[mid].real();
  double d = min(closestpair(a, l, mid), closestpair(a, mid, r));
  inplace_merge(a.begin()+l, a.begin()+mid, a.begin()+r, [](const Point& pa, const Point& pb){
    return pa.imag() < pb.imag();
  });

  Points b;
  for(int i=l; i<r; i++){
    if(abs(a[i].real()-X) >= d) continue;
    for(int j=b.size()-1; j>=0; j--){
      if(abs((a[i]-b[j]).imag()) >= d) break;
      d = min(d, abs(a[i]-b[j]));
    }
    b.push_back(a[i]);
  }
  return d;
}

/* 円の交差判定 */
/* verify: http://judge.u-aizu.ac.jp/onlinejudge/finder.jsp?course=CGL date:2020/10/11 */
int intersectionCC(Circle c1, Circle c2){
  if(c1.r > c2.r) swap(c1, c2);
  double d1 = abs(c1.p-c2.p); 
  double d2 = c1.r + c2.r;
  if(d1 > d2) return 4; /* 互いに交点を持たない */
  else if(d1 == d2) return 3; /* 外接する場合 */
  else{
    if(c2.r == c1.r + d1) return 1; /* 内接する場合 */
    else if(c2.r > c1.r + d1) return 0; /* 包含 */
    else return 2; /* 交点を2つ持つ */
  }
}

/* 点集合が反時計回りに与えられる場合のみ */
double Area(Points &g){
  double res = 0;
  int n = g.size();
  REP(i,n){
    res += cross(g[i], g[(i+1)%n]);
  }
  return res/2.0;
}

/* 内接円 */
/* verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_B&lang=ja date: 2020/10/11 */
pair<Point, double> incircle_of_a_Triangle(Points &p){

  double a = abs(p[1]-p[2]), b = abs(p[2]-p[0]), c = abs(p[0]-p[1]);
  double s = (a+b+c) / 2.0;
  double S = sqrtl(s*(s-a)*(s-b)*(s-c));
  double r = S/s; 
  
  Point pp = (a*p[0]+b*p[1]+c*p[2])/(a+b+c);
  return make_pair(pp, r);
} 

/* 外接円 */
pair<Point, double> circumscribed_circle_of_a_triangle(Points &p){

  Point m1((p[0]+p[1])/2.0), m2((p[1]+p[2])/2.0);
  Point v((p[1]-p[0]).imag(), (p[0]-p[1]).real()), w((p[1]-p[2]).imag(), (p[2]-p[1]).real());

  Line l1(m1, Point(v+m1)), l2(m2, Point(w+m2));

  Point x = crosspoint(l1, l2);
  double r = abs(x-p[0]);
  return make_pair(x, r);
}

/* ある点pを通る円cの接線 */
Points tangent_to_a_circle(Point p, Circle C){
  Points ps;
  double d = abs(C.p-p);
  if(eq(d,0)){
    ps.push_back(p);
  }else if(d>EPS){
    
    double d2 = sqrt(d*d-C.r*C.r);
    
    long double theta = acosl(d2/d);
    //cout << theta << endl;
    Point pp = C.p - p;
    Point p2 = rotate(-theta, pp);

    Point e = p2/abs(p2);
    Point ppp = e*d2;
    ps.push_back(p + ppp);
    p2 = rotate(theta, pp);
    e = p2/abs(p2);
    ppp = e*d2;
    ps.push_back(p + ppp);
    
  }
  return ps;
}

Lines tangent(Circle C1, Circle C2){
  Lines ls;
  if(C1.r < C2.r) swap(C1, C2);
  double d = norm(C1.p - C2.p);
  if(eq(d, 0)) return ls;
  Point u = (C2.p - C1.p) / sqrt(d);
  Point v = rotate(pi/2, u);

  for(double s: {-1, 1}) {
    double h = (C1.r + s * C2.r) / sqrt(d);
    if(eq(1-h*h, 0)) {
      ls.emplace_back(C1.p + u * C1.r, C1.p + (u+v) * C1.r);
    }else if(1-h*h>0){
      Point uu = u*h, vv = v*sqrt(1-h*h);
      ls.emplace_back(C1.p + (uu+vv) * C1.r, C2.p - (uu+vv) * C2.r * s);
      ls.emplace_back(C1.p + (uu-vv) * C1.r, C2.p - (uu-vv) * C2.r * s);
    }
  }
  return ls;
}
Line bisector(Point a, Point b){
    Point A = (a+b)*Point(0.5, 0); 
    return Line(A, A+(b-a)*Point(0, PI/2));
}

Polygon voronoi_cell(Polygon Q, Points P, int s){
    REP(i,P.size()){
        if(i!=s){
            Q = convex_cut(Q, bisector(P[s], P[i]));
        }
    }
    return Q;
}
int main() {  
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(12);
  
  int n, w, d; cin >> n >> w >> d;
  vector<pair<int, int>> vp;
  REP(i,n) {
    int x, y; char c; cin >> x >> y >> c;
    if(c == 'N') {
      vp.push_back({2*d+x-y, x+y});
    }else if(c == 'E') {
      vp.push_back({2*(d+w)-x-y, 2*d+x-y});
    }else if(c == 'W') {
      vp.push_back({x+y,-x+y});
    }else{
      vp.push_back({2*(d+w)-x+y, 2*(d+w)-x-y});
    }
  }
  sort(all(vp));
  int ans = 1e9;
  REP(i,n) {
    auto tmp = vp;
    for(int j=0; j<i; j++) {
      if(tmp[j].first < tmp[i].first) {
        tmp[j].first += 2*(w+d);
        tmp[j].second += 2*(w+d);
      }
    }
    int cnt = 1;
    sort(all(tmp));
    int r = tmp[0].first;
    for(int j=0; j<tmp.size(); j++) {
      if(r < tmp[j].second) {
        r = tmp[j].first;
        cnt++;
      }
    }
    ans = min(ans, cnt);
  }
  cout << ans << endl;
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3508
final_rank: 2

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

int conv(int w, int d, int x, int y) {
  if (x == 0) return y;
  if (y == d) return d+x;
  if (x == w) return w+d*2-y;
  return (w+d)*2-x;
}

using P = pair<int,int>;

int main() {

  ios::sync_with_stdio(false);
  cin.tie(0);

  int n,w,d;
  cin >> n >> w >> d;
  vector<int> x(n),y(n);
  vector<char> f(n);
  for (int i=0;i<n;i++) {
    cin >> x[i] >> y[i] >> f[i];
  }
  vector<int> l(n),r(n);
  for (int i=0;i<n;i++) {
    if (f[i] == 'N') {
      int dl = min(abs(x[i]),abs(y[i]-d));
      int dr = min(abs(x[i]-w),abs(y[i]-d));
      l[i] = conv(w,d,x[i]-dl,y[i]+dl);
      r[i] = conv(w,d,x[i]+dr,y[i]+dr);
    }
    if (f[i] == 'E') {
      int dl = min(abs(x[i]-w),abs(y[i]-d));
      int dr = min(abs(x[i]-w),abs(y[i]));
      l[i] = conv(w,d,x[i]+dl,y[i]+dl);
      r[i] = conv(w,d,x[i]+dr,y[i]-dr);
    }
    if (f[i] == 'S') {
      int dl = min(abs(x[i]-w),abs(y[i]));
      int dr = min(abs(x[i]),abs(y[i]));
      l[i] = conv(w,d,x[i]+dl,y[i]-dl);
      r[i] = conv(w,d,x[i]-dr,y[i]-dr);
    }
    if (f[i] == 'W') {
      int dl = min(abs(x[i]),abs(y[i]));
      int dr = min(abs(x[i]),abs(y[i]-d));
      l[i] = conv(w,d,x[i]-dl,y[i]-dl);
      r[i] = conv(w,d,x[i]-dr,y[i]+dr);
    }
  }
  vector<vector<bool>> ex(n,vector<bool>(n,false));
  for (int i=0;i<n;i++) {
    for (int j=0;j<n;j++) {
      // r[i]
      int vl = l[j];
      int vr = r[j];
      if (vr < vl) {
        vr += 2*(w+d);
      }
      int kr = r[i];
      if (kr < vl) {
        kr += 2*(w+d);
      }
      if (vl <= kr && kr <= vr) {
        ex[i][j] = true;
      }
    }
  }
  int ans = n;
  for (int i=0;i<n;i++) {
    int kans = 1;
    int now = r[i];
    vector<P> ps;
    vector<bool> used(n,false);
    for (int j=0;j<n;j++) {
      if (ex[i][j]) {
        used[j] = true;
        continue;
      }
      int vl = l[j];
      int vr = r[j];
      if (vl < now) vl += 2*(w+d);
      if (vr < now) vr += 2*(w+d);
      ps.emplace_back(P(vl,-(j+1)));
      ps.emplace_back(P(vr,j+1));
    }
    sort(ps.begin(),ps.end());
    queue<int> q;
    for (int j=0;j<ps.size();j++) {
      int ind = abs(ps[j].second)-1;
      if (ps[j].second < 0) {
        q.push(ind);
      }
      else {
        if (used[ind]) continue;
        kans++;
        used[ind] = true;
        while (!q.empty()) {
          int nv = q.front();
          used[nv] = true;
          q.pop();
        }
      }
    }
    ans = min(ans,kans);
  }
  cout << ans << endl;
}
accuracy: 1
time_ms: 60
memory_kb: 3680
final_rank: 16

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

int conv(int w, int d, int x, int y) {
  if (x == 0) return y;
  if (y == d) return d+x;
  if (x == w) return w+d*2-y;
  return (w+d*2)-x;
}

using P = pair<int,int>;

int main() {

  ios::sync_with_stdio(false);
  cin.tie(0);

  int n,w,d;
  cin >> n >> w >> d;
  vector<int> x(n),y(n);
  vector<char> f(n);
  for (int i=0;i<n;i++) {
    cin >> x[i] >> y[i] >> f[i];
  }
  vector<int> l(n),r(n);
  for (int i=0;i<n;i++) {
    if (f[i] == 'N') {
      int dl = min(abs(x[i]),abs(y[i]-d));
      int dr = min(abs(x[i]-w),abs(y[i]-d));
      l[i] = conv(w,d,x[i]-dl,y[i]+dl);
      r[i] = conv(w,d,x[i]+dr,y[i]+dr);
    }
    if (f[i] == 'E') {
      int dl = min(abs(x[i]-w),abs(y[i]-d));
      int dr = min(abs(x[i]-w),abs(y[i]));
      l[i] = conv(w,d,x[i]+dl,y[i]+dl);
      r[i] = conv(w,d,x[i]+dr,y[i]-dr);
    }
    if (f[i] == 'S') {
      int dl = min(abs(x[i]-w),abs(y[i]));
      int dr = min(abs(x[i]),abs(y[i]));
      l[i] = conv(w,d,x[i]+dl,y[i]-dl);
      r[i] = conv(w,d,x[i]-dr,y[i]-dr);
    }
    if (f[i] == 'W') {
      int dl = min(abs(x[i]),abs(y[i]));
      int dr = min(abs(x[i]),abs(y[i]-d));
      l[i] = conv(w,d,x[i]-dl,y[i]-dl);
      r[i] = conv(w,d,x[i]-dr,y[i]+dr);
    }
  }
  vector<vector<bool>> ex(n,vector<bool>(n,false));
  for (int i=0;i<n;i++) {
    for (int j=0;j<n;j++) {
      // r[i]
      int vl = l[j];
      int vr = r[j];
      if (vr < vl) {
        vr += 2*(w+d);
      }
      int kr = r[i];
      if (kr < vl) {
        kr += 2*(w+d);
      }
      if (vl <= kr && kr <= vr) {
        ex[i][j] = true;
      }
    }
  }
  int ans = n;
  for (int i=0;i<n;i++) {
    int kans = 1;
    int now = r[i];
    vector<P> ps;
    vector<bool> used(n,false);
    for (int j=0;j<n;j++) {
      if (ex[i][j]) {
        used[j] = true;
        continue;
      }
      int vl = l[j];
      int vr = r[j];
      if (vl < now) vl += 2*(w+d);
      if (vr < now) vr += 2*(w+d);
      ps.emplace_back(P(vl,-(j+1)));
      ps.emplace_back(P(vr,j+1));
    }
    sort(ps.begin(),ps.end());
    queue<int> q;
    for (int j=0;j<ps.size();j++) {
      int ind = abs(ps[j].second)-1;
      if (ps[j].second < 0) {
        q.push(ind);
      }
      else {
        if (used[ind]) continue;
        kans++;
        used[ind] = true;
        while (!q.empty()) {
          int nv = q.front();
          used[nv] = true;
          q.pop();
        }
      }
    }
    ans = min(ans,kans);
  }
  cout << ans << endl;
}
accuracy: 0.03333333333333333
time_ms: 30
memory_kb: 3444
final_rank: 20

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

const int dx[4] = {-1, 1, 1, -1}, dy[4] = {1, 1, -1, -1};
const int INF = 1e9;

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n, w, d;
    cin >> n >> w >> d;
    auto ctoi = [](char c) {
        if (c == 'N') return 0;
        if (c == 'E') return 1;
        if (c == 'S') return 2;
        return 3;
    };
    auto crosspoint = [&](int x, int y, int f) -> pair<int, int> {
        int Min = INF;
        for (int X : {0, w}) {
            int t = (X - x) * dx[f];
            if (0 <= t && t < Min) Min = t;
        }
        for (int Y : {0, d}) {
            int t = (Y - y) * dy[f];
            if (0 <= t && t < Min) Min = t;
        }
        return {x + dx[f] * Min, y + dy[f] * Min};
    };
    auto idx = [&](pair<int, int> p) {
        int x = p.first, y = p.second;
        if (x == 0) return y;
        if (y == d) return d + x;
        if (x == w) return d + w + (d - y);
        return d + w + d + (w - x);
    };
    vector<vector<int>> wall(n);

    for (int i = 0; i < n; i++) {
        int x, y;
        char c;
        cin >> x >> y >> c;
        int f = ctoi(c);
        for (int j = 0; j < 2; j++) {
            auto p = crosspoint(x, y, (f + j) % 4);
            wall[i].emplace_back(idx(p));
        }
    }

    auto calc = [&](int x) {
        vector<pair<int, int>> v;
        for (int i = 0; i < n; i++) {
            int l = wall[i][0], r = wall[i][1];
            if (l <= r && l <= x && x <= r) continue;
            if (r < l && !(r < x && x < l)) continue;
            if (r < l)
                r += 2 * (w + d);
            else if (r < x)
                l += 2 * (w + d), r += 2 * (w + d);
            v.emplace_back(r, l);
        }
        sort(v.begin(), v.end());

        int cur = x, res = 1;
        for (auto& p : v) {
            if (p.second <= cur) continue;
            cur = p.first;
            res++;
        }
        return res;
    };

    int ans = INF;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < 2; j++) {
            ans = min(ans, calc(wall[i][j]));
        }
    }
    cout << ans << '\n';
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 3536
final_rank: 9

code_snippet: #define LOCAL
#include <bits/stdc++.h>
using namespace std;
#pragma region Macros
typedef long long ll;
typedef __int128_t i128;
typedef unsigned int uint;
typedef unsigned long long ull;
#define ALL(x) (x).begin(), (x).end()

template <typename T> istream& operator>>(istream& is, vector<T>& v) {
    for (T& x : v) is >> x;
    return is;
}
template <typename T> ostream& operator<<(ostream& os, const vector<T>& v) {
    for (int i = 0; i < (int)v.size(); i++) {
        os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
    }
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const map<T, U>& m) {
    os << '{';
    for (auto itr = m.begin(); itr != m.end();) {
        os << '(' << itr->first << ',' << itr->second << ')';
        if (++itr != m.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const unordered_map<T, U>& m) {
    os << '{';
    for (auto itr = m.begin(); itr != m.end();) {
        os << '(' << itr->first << ',' << itr->second << ')';
        if (++itr != m.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const set<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const multiset<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const unordered_set<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const deque<T>& v) {
    for (int i = 0; i < (int)v.size(); i++) {
        os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
    }
    return os;
}

template <int i, typename T> void print_tuple(ostream&, const T&) {}
template <int i, typename T, typename H, class... Args> void print_tuple(ostream& os, const T& t) {
    if (i) os << ',';
    os << get<i>(t);
    print_tuple<i + 1, T, Args...>(os, t);
}
template <typename... Args> ostream& operator<<(ostream& os, const tuple<Args...>& t) {
    os << '{';
    print_tuple<0, tuple<Args...>, Args...>(os, t);
    return os << '}';
}

void debug_out() { cerr << '\n'; }
template <class Head, class... Tail> void debug_out(Head&& head, Tail&&... tail) {
    cerr << head;
    if (sizeof...(Tail) > 0) cerr << ", ";
    debug_out(move(tail)...);
}
#ifdef LOCAL
#define debug(...)                                                                   \
    cerr << " ";                                                                     \
    cerr << #__VA_ARGS__ << " :[" << __LINE__ << ":" << __FUNCTION__ << "]" << '\n'; \
    cerr << " ";                                                                     \
    debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

template <typename T> T gcd(T x, T y) { return y != 0 ? gcd(y, x % y) : x; }
template <typename T> T lcm(T x, T y) { return x / gcd(x, y) * y; }

int topbit(signed t) { return t == 0 ? -1 : 31 - __builtin_clz(t); }
int topbit(long long t) { return t == 0 ? -1 : 63 - __builtin_clzll(t); }
int botbit(signed a) { return a == 0 ? 32 : __builtin_ctz(a); }
int botbit(long long a) { return a == 0 ? 64 : __builtin_ctzll(a); }
int popcount(signed t) { return __builtin_popcount(t); }
int popcount(long long t) { return __builtin_popcountll(t); }
bool ispow2(int i) { return i && (i & -i) == i; }

template <class T> T ceil(T x, T y) {
    assert(y >= 1);
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <class T> T floor(T x, T y) {
    assert(y >= 1);
    return (x > 0 ? x / y : (x - y + 1) / y);
}

template <class T1, class T2> inline bool chmin(T1& a, T2 b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template <class T1, class T2> inline bool chmax(T1& a, T2 b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
#pragma endregion

const int INF = 1e9;
const long long IINF = 1e18;
const char dir[4] = {'D', 'R', 'U', 'L'};
const long long MOD = 1000000007;
// const long long MOD = 998244353;

const int dx[4] = {-1, 1, 1, -1}, dy[4] = {1, 1, -1, -1};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n, w, d;
    cin >> n >> w >> d;
    auto ctoi = [](char c) {
        if (c == 'N') return 0;
        if (c == 'E') return 1;
        if (c == 'S') return 2;
        return 3;
    };
    auto crosspoint = [&](int x, int y, int f) -> pair<int, int> {
        int Min = INF;
        for (int X : {0, w}) {
            int t = (X - x) * dx[f];
            if (0 <= t && t < Min) Min = t;
        }
        for (int Y : {0, d}) {
            int t = (Y - y) * dy[f];
            if (0 <= t && t < Min) Min = t;
        }
        return {x + dx[f] * Min, y + dy[f] * Min};
    };
    auto idx = [&](pair<int, int> p) {
        int x = p.first, y = p.second;
        if (x == 0) return y;
        if (y == d) return d + x;
        if (x == w) return d + w + (d - y);
        return d + w + d + (w - x);
    };
    vector<vector<int>> wall(n);

    for (int i = 0; i < n; i++) {
        int x, y;
        char c;
        cin >> x >> y >> c;
        int f = ctoi(c);
        for (int j = 0; j < 2; j++) {
            auto p = crosspoint(x, y, (f + j) % 4);
            wall[i].emplace_back(idx(p));
        }
    }

    auto calc = [&](int x) {
        vector<pair<int, int>> v;
        for (int i = 0; i < n; i++) {
            int l = wall[i][0], r = wall[i][1];
            if (l <= r && l <= x && x <= r) continue;
            if (r < l && !(r < x && x < l)) continue;
            if (r < l)
                r += 2 * (w + d);
            else if (r < x)
                l += 2 * (w + d), r += 2 * (w + d);
            v.emplace_back(r, l);
        }
        sort(v.begin(), v.end());

        int cur = x, res = 1;
        for (auto& p : v) {
            if (p.second <= cur) continue;
            cur = p.first;
            res++;
        }
        return res;
    };

    int ans = INF;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < 2; j++) {
            ans = min(ans, calc(wall[i][j]));
        }
    }
    cout << ans << '\n';
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3536
final_rank: 7

code_snippet: #include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define Inf 1000000001

int n,w,d;

int get(int x,int y){
	//cout<<x<<','<<y<<endl;
	if(y==0)return x;
	else if(x==w)return w+y;
	else if(y==d)return w+d+(w-x);
	else return w*2+d+(d-y);
}

int get0(int x,int y){
	while(x!=w&&y!=d){
		x++;
		y++;
	}
	return get(x,y);
}

int get1(int x,int y){
	while(x!=0&&y!=d){
		x--;
		y++;
	}
	return get(x,y);
}
int get2(int x,int y){
	while(x!=0&&y!=0){
		x--;
		y--;
	}
	return get(x,y);
}
int get3(int x,int y){
	while(x!=w&&y!=0){
		x++;
		y--;
	}
	return get(x,y);
}

int get(vector<int> l,vector<int> r){
	vector<pair<int,int>> X;
	rep(i,n){
		X.emplace_back(r[i],l[i]);
	}
	
	sort(X.begin(),X.end());
	
	int cur = -1;
	int ret = 0;
	
	rep(i,X.size()){
		int ll = X[i].second,rr = X[i].first;
		if(ll>cur){
			cur = rr;
			ret++;
		}
	}
	return ret;
}


int main(){
	
	cin>>n>>w>>d;
	
	vector<int> l,r;
	
	rep(i,n){
		int x,y;
		cin>>x>>y;
		char c;
		cin>>c;
		
		if(c=='E'){
			l.push_back(get3(x,y));
			r.push_back(get0(x,y));
		}
		if(c=='N'){
			l.push_back(get0(x,y));
			r.push_back(get1(x,y));
		}
		if(c=='W'){
			l.push_back(get1(x,y));
			r.push_back(get2(x,y));
		}
		if(c=='S'){
			l.push_back(get2(x,y));
			r.push_back(get3(x,y));
		}
	}
	
	int ans = n;
	
	int M = w+d;
	M *= 2;
	
	rep(i,n){
		//cout<<l[i]<<','<<r[i]<<endl;
		vector<int> ll = l,rr = r;
		int offset = l[i];
		rep(j,n){
			ll[j] -= offset;
			rr[j] -= offset;
			while(ll[j]<0)ll[j] += M;
			while(rr[j]<0)rr[j] += M;
			if(ll[j]>rr[j]){
				rr[j] = M;
			}
		}
		ans = min(ans,get(ll,rr));
	}
	
	cout<<ans<<endl;
	
	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3520
final_rank: 6

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n,w,d; cin >> n >> w >> d;
    vector<pair<pair<int,int>,int>> v;
    for(int i=1;i<=n;i++){
        int x,y; cin >> x >> y;
        char c; cin >> c;
        if(c=='E'){
            int dif=(w-x);
            if(y-dif>=0)v.push_back(make_pair(make_pair(w,y-dif),i));
            else v.push_back(make_pair(make_pair(x+y,0),i));

            if(y+dif<=d)v.push_back(make_pair(make_pair(w,y+dif),-i));
            else v.push_back(make_pair(make_pair(x+(d-y),d),-i));
        }
        else if(c=='W'){
            int dif=x;
            if(y-dif>=0)v.push_back(make_pair(make_pair(0,y-dif),-i));
            else v.push_back(make_pair(make_pair(x-y,0),-i));

            if(y+dif<=d)v.push_back(make_pair(make_pair(0,y+dif),i));
            else v.push_back(make_pair(make_pair(x-(d-y),d),i));
        }
        else if(c=='S'){
            int dif=y;
            if(x-dif>=0)v.push_back(make_pair(make_pair(x-dif,0),i));
            else v.push_back(make_pair(make_pair(0,y-x),i));

            if(x+dif<=w)v.push_back(make_pair(make_pair(x+dif,0),-i));
            else v.push_back(make_pair(make_pair(w,y-(w-x)),-i));
        }
        else if(c=='N'){
            int dif=(d-y);
            if(x-dif>=0)v.push_back(make_pair(make_pair(x-dif,d),-i));
            else v.push_back(make_pair(make_pair(0,y+x),-i));

            if(x+dif<=w)v.push_back(make_pair(make_pair(x+dif,d),i));
            else v.push_back(make_pair(make_pair(w,y+(w-x)),i));
        }
    }
    auto label=[&](pair<int,int> p)->int{
        if(p.second==d)return 0;
        else if(p.first==w)return 1;
        else if(p.second==0)return 2;
        else return 3;
    };
    auto comp=[&](pair<int,int> i,pair<int,int> j)->int{
        int x=label(i),y=label(j);
        if(x!=y){
            return x<y;
        }
        else if(x==0){
            return i.first<j.first;
        }
        else if(x==1){
            return i.second>j.second;
        }
        else if(x==2){
            return i.first>j.first;
        }
        else{
            return i.second<j.second;
        }
    };
    sort(v.begin(), v.end(),[&](auto i,auto j){
        if(i.first==j.first)return i<j;
        else{
            if(comp(i.first,j.first))return true;
            else return false;
        }
    });
    int res=1e9;
    vector<int> ed(n+1);
    vector<int> be(n+1);
    int N=v.size();
    for(int i=0;i<N;i++){
        // cout << v[i].first.first << " " << v[i].first.second << " " <<  v[i].second << endl;
        fill(ed.begin(), ed.end(),0);
        fill(be.begin(), be.end(),1e9);
        for(int j=0;j<i;j++){
            if(v[j].second<0){
                be[-v[j].second]=j;
            }
            else{
                be[v[j].second]=1e9;
            }
        }
        int ret=0;
        int last=-1;
        for(int cur=i,sum=0;sum<n;cur++){
            int id=cur%N;
            if(v[id].second>0){
                int u=v[id].second;
                if(ed[u])continue;
                if(be[u]<last or v[last%N].first==v[id].first){
                    ed[u]=1;
                    sum++;
                }
                else{
                    last=cur;
                    ret++;
                    sum++;
                    ed[u]=1;
                }
            }
            else{
                be[-v[id].second]=cur;
            }
        }
        res=min(res,ret);
    }
    printf("%d\n",res);
}
accuracy: 1
time_ms: 10
memory_kb: 3656
final_rank: 13