diff --git a/algorithms/graph/lca.cpp b/algorithms/graph/lca.cpp
index 151af9df76b4fdc9f2666eabf6a2781aa2163ac8..a0efdf7c396c2218e7ca56ce806176a38bfe6a13 100644
--- a/algorithms/graph/lca.cpp
+++ b/algorithms/graph/lca.cpp
@@ -60,40 +60,40 @@ struct LCA {
         dfs(u.fi, v, u.se);
   }
 
-  int query(int p, int q) {
+  int query(int a, int b) {
     int ans = 0;
 
-    if (h[p] < h[q])
-      swap(p, q);
+    if (h[a] < h[b])
+      swap(a, b);
 
     for (int i = MAXLOG - 1; i >= 0; --i)
-      if (par[p][i] != -1 && h[par[p][i]] >= h[q]) {
-        ans = op(ans, cost[p][i]);
-        p = par[p][i];
+      if (par[a][i] != -1 && h[par[a][i]] >= h[b]) {
+        ans = op(ans, cost[a][i]);
+        a = par[a][i];
       }
 
-    if (p == q) {
+    if (a == b) {
       #ifdef COST
         return ans;
       #else
-        return p;
+        return a;
       #endif
     }
 
     for (int i = MAXLOG - 1; i >= 0; --i)
-      if (par[p][i] != -1 && par[p][i] != par[q][i]) {
-        ans = op(ans, op(cost[p][i], cost[q][i]));
-        p = par[p][i];
-        q = par[q][i];
+      if (par[a][i] != -1 && par[a][i] != par[b][i]) {
+        ans = op(ans, op(cost[a][i], cost[b][i]));
+        a = par[a][i];
+        b = par[b][i];
       }
 
     #ifdef COST
-      if (p == q) 
+      if (a == b) 
         return ans;
       else 
-        return op(ans, op(cost[p][0], cost[q][0]));
+        return op(ans, op(cost[a][0], cost[b][0]));
     #else
-      return par[p][0];
+      return par[a][0];
     #endif
   }
 };
diff --git a/algorithms/graph/steiner_tree.cpp b/algorithms/graph/steiner_tree.cpp
index 8dcd3d011029c3dfe220b177f5f3e3b12d917ce2..829ac259083f0ad338e4259549691147fa84c7fe 100644
--- a/algorithms/graph/steiner_tree.cpp
+++ b/algorithms/graph/steiner_tree.cpp
@@ -8,7 +8,7 @@
 ///   The algorithm works by using dynamic programming, where dp[i][mask] 
 /// stores the value of a Steiner tree rooted at $i$ containing the terminal
 /// nodes represented by the bits in bitmask. The algorithm iterates over all
-/// bitmasks, and at each iteration $mask$ every pair of complementary subsets
+/// bitmasks, and, at each iteration $mask$, every pair of complementary subsets
 /// are tested and dp[i][mask] is updated with the value given by the 
 /// combination of both trees. Then, still at step $mask$, dp[j][mask] is 
 /// updated for every $j$ with the ``extension'' of $i$ (for every $i$), as if 
@@ -28,13 +28,13 @@ int dp[MAXN][1 << MAXT];
 int steiner_tree(int n, int t) {
   floyd_warshall(n);
 
-  fill(dp[0], dp[0] + MAXN * (1 << MAXT), inf);
+  mset(dp, inf);
   for (int i = 0; i < t; ++i)
     dp[i][1 << i] = 0;
 
   for (int mask = 1; mask < (1 << t); ++mask) {
     for (int i = 0; i < n; ++i)
-      for (int ss = mask; ss > 0; smask = (ss - 1) & mask)
+      for (int ss = mask; ss > 0; ss = (ss - 1) & mask)
         dp[i][mask] = min(dp[i][mask], 
             dp[i][ss] + dp[i][mask ^ ss]);
 
diff --git a/contests/SBC18/B.cpp b/contests/SBC18/B.cpp
index 0931aac673235e5c23807b142565c9b7d7ec871f..d08d5c40e291257b3fb3f9bcc30d4e5d8eeb1bae 100644
--- a/contests/SBC18/B.cpp
+++ b/contests/SBC18/B.cpp
@@ -1,6 +1,5 @@
 #include <bits/stdc++.h>
 
-#define MAX 101
 #define EPS 1e-6
 #define MOD 1000000007
 #define inf 0x3f3f3f3f
@@ -21,53 +20,48 @@ using ll = long long;
 using ii = pair<int,int>;
 
 int foi[500];
-int mat[MAX][MAX];
-int dp[MAX][MAX];
+int dp[102][102];
 
 int main() {
   ios::sync_with_stdio(0);
   cin.tie(0);
 
-  for (int i = 0; i < MAX; ++i) {
-    dp[i][0] = 499;
-    dp[0][i] = 499;
+  int N = 100;
+  for (int i = 0; i < N; ++i) {
     dp[i][i] = 499;
+    dp[0][i] = 499;
+    dp[i][0] = 499;
   }
 
-  for (int i = 1; i < MAX; ++i) {
-    for (int j = 1; j < MAX; ++j) {
+  for (int i = 1; i <= N; ++i) {
+    for (int j = 1; j <= N; ++j) {
       if (i != j) {
         mset(foi, 0);
         for (int k = 1; k <= i; ++k)
           foi[dp[i-k][j]] = 1;
         for (int k = 1; k <= j; ++k)
           foi[dp[i][j-k]] = 1;
-
-        int mm = min(i, j);
-        for (int k = 1; k <= mm; ++k)
+        for (int k = 1; k <= min(i, j); ++k)
           foi[dp[i-k][j-k]] = 1;
 
-        int res = -1;
-        for (int k = 0; k < 500; ++k)
+        for (int k = 0; k <= 500; ++k)
           if (!foi[k]) {
-            res = k;
+            dp[i][j] = k;
             break;
           }
-
-        dp[i][j] = res;
       }
     }
   }
-
-  int ans = 0;
+   
   int n; cin >> n;
+  int ans = 0;
   for (int i = 0; i < n; ++i) {
-    int a, b; cin >> a >> b; 
-    if (dp[a][b] == 499)
+    int a, b; cin >> a >> b;
+    if (a == b)
       return cout << 'Y' << ende, 0;
     ans ^= dp[a][b];
   }
 
-  cout << ((ans) ? 'Y' : 'N') << ende;
+  cout << (ans ? 'Y' : 'N') << ende;
   return 0;
 }
diff --git a/contests/SBC18/C.cpp b/contests/SBC18/C.cpp
index 7b79559b04afff8d1d2b8300d905e6212d2946ac..818af61c570f56f401c12dd02b3342d695a75b5d 100644
--- a/contests/SBC18/C.cpp
+++ b/contests/SBC18/C.cpp
@@ -1,14 +1,13 @@
 #include <bits/stdc++.h>
 
 #define MAX 101010
-#define MOD 1000000007
 #define EPS 1e-6
+#define MOD 1000000007
 #define inf 0x3f3f3f3f
 #define llinf 0x3f3f3f3f3f3f3f3f
 
 #define fi first
 #define se second
-#define sz size()
 #define pb push_back
 #define ende '\n'
 
@@ -18,74 +17,65 @@
 
 using namespace std; 
 
-typedef long long ll;
-typedef pair<ll,ll> ii;
+using ll = long long;
+using ii = pair<int,int>;
 
-ll tree[MAX];
+int tree[MAX];
 
-ll query(int idx) {
-  ll sum = 0;
-  for (; idx > 0; idx -= (idx & -idx))
+int query(int idx) {
+  int sum = 0;
+  for ( ; idx > 0; idx -= (idx & -idx))
     sum += tree[idx];
-
   return sum;
 }
 
-
-void update(int idx, ll val) {
-  for (; idx <= MAX; idx += (idx & -idx))
+void update(int idx, int val) {
+  for ( ; idx < MAX; idx += (idx & -idx))
     tree[idx] += val;
 }
 
-
 int main() {
   ios::sync_with_stdio(0);
   cin.tie(0);
 
-  ll x, y; cin >> x >> y;
-  ll h, v; cin >> h >> v;
-
-  ll a, b;
-  vector<ii> H, V;
-  vector<ll> h1, v1;
-  vector<ll> hh, vv;
-  map<ll,ll> Mh, Mv;
+  int x, y; cin >> x >> y;
+  int h, v; cin >> h >> v;
+  vector<ii> H(h), V(v);
 
-  for (ll i = 0; i < h; ++i) {
-    cin >> a >> b;
-    H.pb(ii(b, a));
-    h1.pb(a);
+  for (int i = 0; i < h; ++i) {
+    int x1, x2; cin >> x1 >> x2;
+    H[i] = ii(x1, x2);
   }
 
-  for (ll i = 0; i < v; ++i) {
-    cin >> a >> b;
-    V.pb(ii(b, a));
-    v1.pb(a);
+  for (int i = 0; i < v; ++i) {
+    int y1, y2; cin >> y1 >> y2;
+    V[i] = ii(y1, y2);
   }
 
   sort(all(H));
-  sort(all(V));
-  sort(all(v1));
-  sort(all(h1));
-
-  for (int i = 0; i < h; ++i) Mh[h1[i]] = i + 1;
-  for (int i = 0; i < v; ++i) Mv[v1[i]] = i + 1;
-
-  for (auto i : H) hh.pb(Mh[i.se]);
-  for (auto i : V) vv.pb(Mv[i.se]);
+  for (int i = 0; i < h; ++i)
+    H[i].fi = i + 1;
+  sort(all(H), [](ii a, ii b) {
+    return a.se < b.se;
+  });
 
-  ll ans = (h + 1) * (v + 1);
+  sort(all(V));
+  for (int i = 0; i < v; ++i)
+    V[i].fi = i + 1;
+  sort(all(V), [](ii a, ii b) {
+    return a.se < b.se;
+  });
 
-  mset(tree, 0);
+  ll ans = (h + 1LL) * (v + 1LL);
   for (int i = h - 1; i >= 0; --i) {
-    ans += query(hh[i]);
-    update(hh[i], 1);
+    ans += query(H[i].fi);
+    update(H[i].fi, 1);
   }
-
+  
   mset(tree, 0);
   for (int i = v - 1; i >= 0; --i) {
-    ans += query(vv[i]);
-    update(vv[i], 1);
+    ans += query(V[i].fi);
+    update(V[i].fi, 1);
   }
 
   cout << ans << ende;
diff --git a/contests/SBC18/D.cpp b/contests/SBC18/D.cpp
index d3ec046fa9dc0209e1482b9a05e4c3a89d3d31bf..ebfbb3e8b597d8d171e89ef14573fb85815c2fcf 100644
--- a/contests/SBC18/D.cpp
+++ b/contests/SBC18/D.cpp
@@ -1,14 +1,12 @@
 #include <bits/stdc++.h>
 
-#define MAX 0
-#define MOD 1000000007
 #define EPS 1e-6
+#define MOD 1000000007
 #define inf 0x3f3f3f3f
 #define llinf 0x3f3f3f3f3f3f3f3f
 
 #define fi first
 #define se second
-#define sz size()
 #define pb push_back
 #define ende '\n'
 
@@ -18,21 +16,20 @@
 
 using namespace std; 
 
-typedef long long ll;
-typedef pair<int,int> ii;
+using ll = long long;
+using ii = pair<int,int>;
 
 int main() {
   ios::sync_with_stdio(0);
   cin.tie(0);
 
-  int ans = 0;
   int n; cin >> n;
+  int ans = 0;
   for (int i = 0; i < n; ++i) {
     int x; cin >> x;
-    if (x != 1) ans++;
+    ans += (x != 1);
   }
 
   cout << ans << ende;
-
   return 0;
 }
diff --git a/contests/SBC18/E.cpp b/contests/SBC18/E.cpp
index caf757e9178d9d87c85ba2e9a2a1b9aba5a6c0ec..8e3600cca06ea3354f3c9df4e9e2f6d24a818dfe 100644
--- a/contests/SBC18/E.cpp
+++ b/contests/SBC18/E.cpp
@@ -1,14 +1,12 @@
 #include <bits/stdc++.h>
 
-#define MAX 0
-#define MOD 1000000007
 #define EPS 1e-6
+#define MOD 1000000007
 #define inf 0x3f3f3f3f
 #define llinf 0x3f3f3f3f3f3f3f3f
 
 #define fi first
 #define se second
-#define sz size()
 #define pb push_back
 #define ende '\n'
 
@@ -18,25 +16,25 @@
 
 using namespace std; 
 
-typedef long long ll;
-typedef pair<int,int> ii;
+using ll = long long;
+using ii = pair<int,int>;
 
 int main() {
   ios::sync_with_stdio(0);
   cin.tie(0);
 
-  string a, b;
-  cin >> a >> b;
-
-  int na = a.sz, nb = b.sz;
-  int ans = na - nb + 1;
-  for (int i = 0; i <= na - nb; ++i) {
-    for (int j = 0; j < nb; ++j) {
-      if (b[j] == a[i+j]) {
-        ans--;
+  string s, t; cin >> s >> t;
+  int ans = 0;
+  for (int i = 0; i <= s.size() - t.size(); ++i) {
+    bool poss = true;
+    for (int j = 0; j < t.size(); ++j)
+      if (s[i+j] == t[j]) {
+        poss = false;
         break;
       }
-    }
+
+    if (poss) 
+      ans++;
   }
 
   cout << ans << ende;
diff --git a/contests/SBC18/F.cpp b/contests/SBC18/F.cpp
index d91a9daa896d432bf3ff3dc716515de731c06381..294882d1e8bfb6ff89cb6e3713419a02095b942b 100644
--- a/contests/SBC18/F.cpp
+++ b/contests/SBC18/F.cpp
@@ -1,14 +1,12 @@
 #include <bits/stdc++.h>
 
-#define MAX 0
-#define MOD 1000000007
 #define EPS 1e-6
+#define MOD 1000000007
 #define inf 0x3f3f3f3f
 #define llinf 0x3f3f3f3f3f3f3f3f
 
 #define fi first
 #define se second
-#define sz size()
 #define pb push_back
 #define ende '\n'
 
@@ -18,59 +16,61 @@
 
 using namespace std; 
 
-typedef long long ll;
-typedef pair<int,int> ii;
+using ll = long long;
+using ii = pair<int,int>;
 
-typedef struct elem {
-  int i, f, o, p;
-  elem(int i, int f, int o, int p) : i(i), f(f), o(o), p(p) {}
-} elem;
+struct Show { int i, f, o, s, nxt; };
 
-int n;
-vector<elem> v;
-int prox[1010];
-int dp[1010][1300];
+int N, S;
+vector<Show> v;
+int dp[1010][3010];
 
-int solve(int i, int bit) {
-  if (i == -1 or i == v.sz) {
-    if (bit == (1 << n) - 1) return 0;
-    else return -inf;
+int solve(int i, int mask) {
+  if (i == N) {
+    if (mask == (1 << S) - 1)
+      return 0;
+    return -inf;
   }
 
-  if (dp[i][bit] != -1)
-    return dp[i][bit];
-
-  return dp[i][bit] = max(solve(prox[i], bit | (1 << v[i].p)) + v[i].o, solve(i + 1, bit));
+  if (dp[i][mask] != -1)
+    return dp[i][mask];
+  
+  int op1 = solve(v[i].nxt, mask | (1 << v[i].s)) + v[i].o;
+  int op2 = solve(i + 1, mask);
+  return dp[i][mask] = max(op1, op2);
 }
 
-
 int main() {
   ios::sync_with_stdio(0);
   cin.tie(0);
 
-  mset(dp, -1);
-  mset(prox, -1);
-  cin >> n;
+  int n; cin >> n;
+  S = n;
   for (int i = 0; i < n; ++i) {
     int m; cin >> m;
     for (int j = 0; j < m; ++j) {
-      int a, b, c; cin >> a >> b >> c;
-      v.pb(elem(a, b, c, i));
+      int ii, ff, oo; cin >> ii >> ff >> oo;
+      v.pb({ii, ff, oo, i, -1});
     }
   }
 
-  sort(all(v), [](elem a, elem b) {
-    return a.i < b.i;    
+  sort(all(v), [](Show a, Show b) {
+    return a.i < b.i;
   });
 
-  for (int i = 0; i < v.sz; ++i)
-    for (int j = i + 1; j < v.sz; ++j)
+  N = v.size();
+  for (int i = 0; i < N; ++i) {
+    for (int j = i + 1; j < N; ++j)
       if (v[j].i >= v[i].f) {
-        prox[i] = j;
+        v[i].nxt = j;
         break;
       }
 
-  int ans = solve(0, 0);
-  cout << ((ans < 0) ? -1 : ans) << ende;
+    if (v[i].nxt == -1)
+      v[i].nxt = N;
+  }
+
+  mset(dp, -1);
+  cout << max(-1, solve(0, 0)) << ende;
   return 0;
 }
diff --git a/contests/SBC18/G.cpp b/contests/SBC18/G.cpp
index 736aa3970ae7b5300174aea139139fd356b03f02..a96f5ceba6d8d1212d905c282cf2cc73bb7cdeba 100644
--- a/contests/SBC18/G.cpp
+++ b/contests/SBC18/G.cpp
@@ -1,6 +1,5 @@
 #include <bits/stdc++.h>
 
-#define MAX 3010
 #define EPS 1e-6
 #define MOD 1000000007
 #define inf 0x3f3f3f3f
@@ -17,139 +16,120 @@
 
 using namespace std; 
 
-typedef long long ll;
-typedef pair<int,int> ii;
+using ll = long long;
+using ii = pair<int,int>;
+using iii = pair<ii,int>;
 
-struct edge {
-  int u;
-  int flow, cap;
-  int rev;
-
-  edge(int u, int flow, int cap, int rev) :
-    u(u), flow(flow), cap(cap), rev(rev)
-  {}
-};
-
-
-int depth[MAX];
-int start[MAX];
-vector<edge> graph[MAX];
+struct Dinic {
+  struct Edge { int u, f, c, r; };
 
+  int N;
+  vector<int> depth, start;
+  vector<vector<Edge>> graph;
 
-void add_edge(int s, int t, int c) {
-  edge forward(t, 0, c, graph[t].size());
-  edge backward(s, 0, 0, graph[s].size());
+  Dinic(int N) : 
+    N(N), depth(N), start(N), graph(N) {}
 
-  graph[s].pb(forward);
-  graph[t].pb(backward);
-}
+  void add_edge(int u, int v, int c) {
+    Edge forw = { v, 0, c, (int) graph[v].size() };
+    Edge back = { u, 0, 0, (int) graph[u].size() };
+    graph[u].pb(forw);
+    graph[v].pb(back);
+  }
 
+  bool bfs(int s, int t) {
+    queue<int> Q;
+    Q.push(s);
 
-bool bfs(int s, int t) {
-  queue<int> Q;
-  Q.push(s);
+    fill(all(depth), -1);
+    depth[s] = 0;
 
-  mset(depth, -1);
-  depth[s] = 0;
+    while (!Q.empty()) {
+      int v = Q.front(); Q.pop();
 
-  while (!Q.empty()) {
-    int v = Q.front(); Q.pop();
-    
-    for (auto i : graph[v]) {
-      if (depth[i.u] == -1 && i.flow < i.cap) {
-        depth[i.u] = depth[v] + 1;
-        Q.push(i.u);
-      }
+      for (auto i : graph[v])
+        if (depth[i.u] == -1 && i.f < i.c) {
+          depth[i.u] = depth[v] + 1;
+          Q.push(i.u);
+        }
     }
-  }
-
-  return depth[t] != -1;
-}
 
+    return depth[t] != -1;
+  }
 
-int dfs(int s, int t, int flow) {
-  if (s == t)
-    return flow;
+  int dfs(int s, int t, int f) {
+    if (s == t) return f;
 
-  for ( ; start[s] < graph[s].size(); ++start[s]) {
-    edge &e = graph[s][start[s]];
+    for ( ; start[s] < graph[s].size(); ++start[s]) {
+      Edge &e = graph[s][start[s]];
 
-    if (depth[e.u] == depth[s] + 1 && e.flow < e.cap) {
-      int min_flow = dfs(e.u, t, min(flow, e.cap - e.flow));
+      if (depth[e.u] == depth[s] + 1 && e.f < e.c) {
+        int min_f = dfs(e.u, t, min(f, e.c - e.f));
 
-      if (min_flow > 0) {
-        e.flow += min_flow;
-        graph[e.u][e.rev].flow -= min_flow;
-        return min_flow;
+        if (min_f > 0) {
+          e.f += min_f;
+          graph[e.u][e.r].f -= min_f;
+          return min_f;
+        }
       }
     }
-  }
-
-  return 0;
-}
-
-
-int dinic(int s, int t) {
-  int ans = 0;
-
-  while (bfs(s, t)) {
-    mset(start, 0);
 
-    while (int flow = dfs(s, t, inf))
-      ans += flow;
+    return 0;
   }
 
-  return ans;
-}
-
+  int run(int s, int t) {
+    int ans = 0;
+    while (bfs(s, t)) {
+      fill(all(start), 0);
+      while (int flow = dfs(s, t, inf))
+        ans += flow;
+    }
+    return ans;
+  }
+};
 
 int main() {
   ios::sync_with_stdio(0);
   cin.tie(0);
 
   int p, r, c; cin >> p >> r >> c;
-  int s = 0, t = MAX - 1;
-  int dem = 0;
+  vector<int> vp(p);
+  vector<int> vr(r);
 
-  vector<int> dems(p);
-  for (auto &i : dems) {
+  int sum = 0;
+  for (auto &i : vp) {
     cin >> i;
-    dem += i;
+    sum += i;
   }
 
-  vector<int> ests(r);
-  for (auto &i : ests) cin >> i;
+  for (auto &i : vr) cin >> i;
 
-  vector<pair<ii,int>> total;
+  vector<iii> v(c);
   for (int i = 0; i < c; ++i) {
-    int a, b, T; cin >> a >> b >> T;
-    total.pb(make_pair(ii(a, b), T));
+    int a, b, x; cin >> a >> b >> x;
+    v[i] = {{a, b}, x};
   }
 
-
-  int L = 0, R = 1010101;
-  for (int i = 0; i < 20; ++i) {
+  int L = 0, R = 1001000;
+  for (int i = 0; i < 30; ++i) {
     int m = (L + R) / 2;
 
-    for (int j = 0; j < p; ++j)
-      add_edge(j + 1 + r, t, dems[j]);
-
+    Dinic dinic(r + p + 5);
     for (int j = 0; j < r; ++j)
-      add_edge(s, j + 1, ests[j]);
-
-    for (auto j : total) 
-      if (j.se <= m)
-        add_edge(j.fi.se, j.fi.fi + r, inf);
+      dinic.add_edge(0, j + 1, vr[j]);
+    for (int j = 0; j < p; ++j)
+      dinic.add_edge(j + 1 + r, r + p + 4, vp[j]);
 
-    if (dinic(s, t) < dem)
-      L = m + 1;
-    else
-      R = m - 1;
+    for (int j = 0; j < c; ++j)
+      if (v[j].se <= m)
+        dinic.add_edge(v[j].fi.se, v[j].fi.fi + r, inf);
 
-    for (int j = 0; j < MAX; ++j)
-      graph[j].clear();
+    if (dinic.run(0, r + p + 4) < sum) 
+      L = m;
+    else 
+      R= m;
   }
 
-  cout << (L >= 1010101 ? -1 : L) << ende;
+  cout << ((R > 1000100) ? -1 : R) << ende;
   return 0;
 }
diff --git a/contests/SBC18/I.cpp b/contests/SBC18/I.cpp
index c44abef09c104a5fcb400c3569f0b589f559992a..637a876b682e7871347b4afbaa95a6026ee85b23 100644
--- a/contests/SBC18/I.cpp
+++ b/contests/SBC18/I.cpp
@@ -1,14 +1,12 @@
 #include <bits/stdc++.h>
 
-#define MAX 0
-#define MOD 1000000007
 #define EPS 1e-6
+#define MOD 1000000007
 #define inf 0x3f3f3f3f
 #define llinf 0x3f3f3f3f3f3f3f3f
 
 #define fi first
 #define se second
-#define sz size()
 #define pb push_back
 #define ende '\n'
 
@@ -18,44 +16,45 @@
 
 using namespace std; 
 
-typedef long long ll;
-typedef pair<int,int> ii;
-
-bool v[1010];
-vector<int> u[1010];
+using ll = long long;
+using ii = pair<int,int>;
 
 int main() {
   ios::sync_with_stdio(0);
   cin.tie(0);
 
-  int x, y;
   int n, m; cin >> n >> m;
   int l; cin >> l;
+  int acc = 0;
+
+  vector<int> lamp(m);
   for (int i = 0; i < l; ++i) {
-    cin >> x;
-    v[x] = true;
+    int x; cin >> x; x--;
+    lamp[x] = 1;
+    acc++;
   }
 
+  vector<vector<int>> inte(n);
   for (int i = 0; i < n; ++i) {
-    cin >> x;
-    for (int j = 0; j < x; ++j) {
-      cin >> y;
-      u[i].pb(y);
+    int k; cin >> k;
+    for (int j = 0; j < k; ++j) {
+      int x; cin >> x; x--;
+      inte[i].pb(x);
     }
   }
 
+  if (acc == 0)
+    return cout << 0 << ende, 0;
+
   int ans = 0;
   for (int i = 0; i < 2; ++i) {
     for (int j = 0; j < n; ++j) {
-      for (auto k : u[j])
-        v[k] = !v[k];
-
       ans++;
-      bool done = true;
-      for (int k = 1; k <= m; ++k)
-        done &= !v[k];
+      for (auto k : inte[j])
+        if (lamp[k]) { acc--; lamp[k] = 0; }
+        else { acc++; lamp[k] = 1; }
 
-      if (done) 
+      if (acc == 0)
         return cout << ans << ende, 0;
     }
   }
diff --git a/contests/SBC18/J.cpp b/contests/SBC18/J.cpp
index 9401290795e10f308d23125f3a93bef54cd9c8ce..8aa4ea5415d63aa518f6b17e8cea70074a3cad5d 100644
--- a/contests/SBC18/J.cpp
+++ b/contests/SBC18/J.cpp
@@ -1,5 +1,7 @@
 #include <bits/stdc++.h>
 
+#define MAX 105
+#define MAXT 11
 #define EPS 1e-6
 #define MOD 1000000007
 #define inf 0x3f3f3f3f
@@ -18,9 +20,10 @@ using namespace std;
 
 using ll = long long;
 using ii = pair<int,int>;
+using dd = pair<double,double>;
 
-double graph[101][101];
-double dp[101][2100];
+double dist[MAX][MAX];
+double dp[MAX][1 << MAXT];
 
 int main() {
   ios::sync_with_stdio(0);
@@ -28,30 +31,30 @@ int main() {
   cout << setprecision(5) << fixed;
 
   int n, k; cin >> n >> k;
-  vector<double> x(n), y(n);
+  vector<dd> v(n);
   for (int i = 0; i < n; ++i)
-    cin >> x[i] >> y[i];
+    cin >> v[i].fi >> v[i].se;
 
   for (int i = 0; i < n; ++i)
     for (int j = 0; j < n; ++j)
-      graph[i][j] = hypot(x[i] - x[j], y[i] - y[j]);
+      dist[i][j] = hypot(v[i].fi - v[j].fi, v[i].se - v[j].se);
 
-  fill(dp[0], dp[0] + 101 * 2100, 1e9);
+  fill(dp[0], dp[0] + (MAX * (1 << MAXT)), 1e9);
   for (int i = 0; i < k; ++i)
-    dp[i][1<<i] = 0;
+    dp[i][1 << i] = 0;
 
-  for (int mask = 0; mask < (1 << k); ++mask) {
+  for (int mask = 1; mask < (1 << k); ++mask) {
     for (int i = 0; i < n; ++i)
       for (int ss = mask; ss > 0; ss = (ss - 1) & mask)
-        dp[i][mask] = min(dp[i][mask], dp[i][ss] + dp[i][mask - ss]);
+        dp[i][mask] = min(dp[i][mask], dp[i][ss] + dp[i][mask ^ ss]);
 
     for (int i = 0; i < n; ++i)
       for (int j = k; j < n; ++j)
-        dp[j][mask] = min(dp[j][mask], dp[i][mask] + graph[i][j]);
+        dp[j][mask] = min(dp[j][mask], dp[i][mask] + dist[i][j]);
   }
-  
+
   double ans = 1e9;
-  for (int i = k; i < n; ++i)
+  for (int i = 0; i < n; ++i)
     ans = min(ans, dp[i][(1 << k) - 1]);
   cout << ans << ende;
   return 0;
diff --git a/contests/SBC18/L.cpp b/contests/SBC18/L.cpp
index e0452563d414cd91d0012b04674faaa5b18eb490..49872438e144ee0f8a4736b387a3d12dfd2cd118 100644
--- a/contests/SBC18/L.cpp
+++ b/contests/SBC18/L.cpp
@@ -1,14 +1,14 @@
 #include <bits/stdc++.h>
 
 #define MAX 101010
-#define MOD 1000000007
+#define MLOG 17
 #define EPS 1e-6
+#define MOD 1000000007
 #define inf 0x3f3f3f3f
 #define llinf 0x3f3f3f3f3f3f3f3f
 
 #define fi first
 #define se second
-#define sz size()
 #define pb push_back
 #define ende '\n'
 
@@ -18,116 +18,83 @@
 
 using namespace std; 
 
-typedef long long ll;
-typedef pair<int,int> ii;
+using ll = long long;
+using ii = pair<int,int>;
 
 int h[MAX];
-int par[MAX][20];
+int par[MAX][MLOG];
 vector<int> graph[MAX];
 
-
-void dfs(int v, int p = -1) {
-  par[v][0] = p;
+void dfs(int x, int p) {
+  par[x][0] = p;
 
   if (p != -1)
-    h[v] = h[p] + 1;
+    h[x] = h[p] + 1;
 
-  for (int i = 1; i < 20; ++i)
-    if (par[v][i-1] != -1)
-      par[v][i] = par[par[v][i-1]][i-1];
+  for (int i = 1; i < MLOG; ++i)
+    if (par[x][i-1] != -1)
+      par[x][i] = par[par[x][i-1]][i-1];
 
-  for (auto u : graph[v])
-    if (p != u)
-      dfs(u, v);
+  for (auto i : graph[x])
+    if (i != p)
+      dfs(i, x);
 }
 
+int lca(int a, int b) {
+  if (h[a] < h[b])
+    swap(a, b);
 
-int lca(int p, int q) {
-  if (h[p] < h[q])
-    swap(p, q);
+  for (int i = MLOG - 1; i >= 0; --i)
+    if (par[a][i] != -1 && h[par[a][i]] >= h[b])
+      a = par[a][i];
 
-  for (int i = 19; i >= 0; --i)
-    if (par[p][i] != -1 and h[par[p][i]] >= h[q])
-      p = par[p][i];
+  if (a == b)
+    return a;
 
-  if (p == q)
-    return p;
-
-  for (int i = 19; i >= 0; --i)
-    if (par[p][i] != -1 and par[p][i] != par[q][i]) {
-      p = par[p][i];
-      q = par[q][i];
+  for (int i = MLOG - 1; i >= 0; --i)
+    if (par[a][i] != -1 && par[a][i] != par[b][i]) {
+      a = par[a][i];
+      b = par[b][i];
     }
 
-  return par[p][0];
+  return par[a][0];
 }
 
-
 int main() {
   ios::sync_with_stdio(0);
   cin.tie(0);
 
-  int a, b, c, d;
   int n, q; cin >> n >> q;
   for (int i = 0; i < n - 1; ++i) {
-    cin >> a >> b;
+    int a, b; cin >> a >> b; a--, b--;
     graph[a].pb(b);
     graph[b].pb(a);
   }
 
+  mset(h, 0);
   mset(par, -1);
-  dfs(1);
+  dfs(0, -1);
 
   for (int i = 0; i < q; ++i) {
-    cin >> a >> b >> c >> d;
-
-    int lab = lca(a, b);
-    int lac = lca(a, c);
-    int lad = lca(a, d);
-    int lbc = lca(b, c);
-    int lbd = lca(b, d);
-    int lcd = lca(c, d);
-
-    // If path C->D is above (or different subtree) than A->B and has no intersection
-    if (h[lca(c, lab)] < h[lab] and h[lca(d, lab)] < h[lab])
-      cout << 0 << ende;
-
-    // If path A->B is above (or different subtree) than C->D and has no intersection
-    else if (h[lca(a, lcd)] < h[lcd] and h[lca(b, lcd)] < h[lcd])
-      cout << 0 << ende;
-
-    // There is an intersection
-    else {
-
-      // If lca(A, B) belongs to the path C->D
-      if (h[lcd] < h[lab]) {
-        
-        // If intersection occurs between C->lca(C,D)
-        if (h[lac] > h[lcd] or h[lbc] > h[lcd]) cout << abs(h[lca(lac, c)] - h[lca(lbc, c)]) + 1 << ende; 
-
-        // If intersection occurs between D->lca(C,D)
-        else cout << abs(h[lca(lad, d)] - h[lca(lbd, d)]) + 1 << ende;
-
-
-      // If lca(C, D) belongs to the path A->B
-      } else if (h[lab] < h[lcd]) {
-
-       // If intersection occurs between A->lca(A,B)
-        if (h[lac] > h[lab] or h[lad] > h[lab]) cout << abs(h[lca(lac, a)] - h[lca(lad, a)]) + 1 << ende;
-
-        // If intersection occurs between B->lca(A,B)
-        else cout << abs(h[lca(lbc, b)] - h[lca(lbd, b)]) + 1 << ende;
-
-
-      // It means that lca(A, B) is the same node as lca(C, D)
-      } else {
-
-        // If A and C are on the same side -> B and D are on the same side
-        if (h[lac] > h[lcd] or h[lbd] > h[lcd]) cout << (h[lac] - h[lcd]) + (h[lbd] - h[lcd]) + 1 << ende; 
-
-        // If A and D are on the same side -> B and C are on the same side
-        else cout << (h[lad] - h[lcd]) + (h[lbc] - h[lcd]) + 1 << ende;
-      }
+    int a, b, c, d; 
+    cin >> a >> b >> c >> d; a--, b--, c--, d--;
+    vector<int> v = { lca(a, c), lca(a, d), lca(b, c), lca(b, d) };
+
+    sort(all(v), [&](int a, int b) {
+      return h[a] > h[b];
+    });
+
+    if (v[0] == v[1]) {
+      bool t1 = ((lca(a, v[0]) == v[0] || lca(b, v[0]) == v[0]) && h[lca(a, b)] <= h[v[0]]);
+      bool t2 = ((lca(c, v[0]) == v[0] || lca(d, v[0]) == v[0]) && h[lca(c, d)] <= h[v[0]]);
+      cout << (t1 && t2) << ende;
+    } else {
+      int aux = lca(v[0], v[1]);
+
+      if (aux == v[0] || aux == v[1])
+        cout << abs(h[v[0]] - h[v[1]]) + 1 << ende;
+      else
+        cout << (h[v[0]] - h[aux] + 1) + (h[v[1]] - h[aux] + 1) - 1 << ende;
     }
   }