diff --git a/mo/web/org_contest.py b/mo/web/org_contest.py
index 6bbc463d1287bc56f83a29499f6dd8c1dd30d906..552a569e0d0166feee1183de3b9367fe1fec764a 100644
--- a/mo/web/org_contest.py
+++ b/mo/web/org_contest.py
@@ -8,7 +8,7 @@ import json
 import locale
 import magic
 from markupsafe import Markup
-from sqlalchemy import func, and_, select, not_
+from sqlalchemy import func, and_, not_
 from sqlalchemy.orm import joinedload, aliased
 from sqlalchemy.orm.query import Query
 from sqlalchemy.dialects.postgresql import insert as pgsql_insert
@@ -28,6 +28,7 @@ import mo.jobs.protocols
 import mo.jobs.submit
 from mo.rights import Right, RoundRights
 import mo.util
+from mo.util import assert_not_none
 from mo.util_format import inflect_number, inflect_by_number, inflect_with_number
 from mo.web import app
 import mo.web.fields as mo_fields
@@ -1533,12 +1534,12 @@ def org_contest_advance(ct_id: int):
     reject_by_place_id: Dict[int, int] = {}
     prev_pions_by_place_id: Dict[int, List[Tuple[db.Participation, Optional[decimal.Decimal], bool]]] = {}
 
-    desc_cte = db.place_descendant_cte(contest.place, max_level=prev_round.level)
-    prev_contests = (sess.query(db.Contest)
-                     .filter(db.Contest.round == prev_round)
-                     .filter(db.Contest.place_id.in_(select([desc_cte])))
-                     .options(joinedload(db.Contest.place))
-                     .all())
+    prev_contests_q = sess.query(db.Contest).filter(db.Contest.round == prev_round)
+    if prev_round.level >= round.level:
+        prev_contests_q = prev_contests_q.join(db.RegionDescendant, and_(db.RegionDescendant.region == contest.place_id, db.RegionDescendant.descendant == db.Contest.place_id))
+    else:
+        prev_contests_q = prev_contests_q.join(db.RegionDescendant, and_(db.RegionDescendant.descendant == contest.place_id, db.RegionDescendant.region == db.Contest.place_id))
+    prev_contests = prev_contests_q.options(joinedload(db.Contest.place)).all()
     prev_contests.sort(key=lambda c: locale.strxfrm(c.place.name or ""))
 
     form = AdvanceForm()
@@ -1553,6 +1554,12 @@ def org_contest_advance(ct_id: int):
         prev_pion_query = (sess.query(db.Participation)
                            .filter(db.Participation.contest_id.in_([c.contest_id for c in prev_contests]))
                            .filter_by(state=db.PartState.active))
+        if prev_round.level < round.level:
+            prev_pion_query = (prev_pion_query
+                               .join(db.Participant, and_(db.Participant.user_id == db.Participation.user_id,
+                                                          db.Participant.year == round.year))
+                               .join(db.RegionDescendant, and_(db.RegionDescendant.descendant == db.Participant.school,
+                                                               db.RegionDescendant.region == contest.place_id)))
         if want_select:
             prev_pions = prev_pion_query.options(joinedload(db.Participation.user)).all()
         else:
@@ -1581,9 +1588,9 @@ def org_contest_advance(ct_id: int):
         really_inserted = 0
         for pp in prev_pions:
             # This incurs no real queries as we have all the contests cached
-            prev_place_id = sess.query(db.Contest).get(pp.contest_id).place_id
-            points = points_map[pp.user_id] if pp.user_id in points_map else None
-            checked = points is not None and points >= form.boundary.data
+            prev_place_id = assert_not_none(sess.query(db.Contest).get(pp.contest_id)).place_id
+            points = points_map.get(pp.user_id, 0)
+            checked = points >= form.boundary.data
             prev_pions_by_place_id[prev_place_id].append((pp, points, checked))
 
             if want_execute and want_select:
@@ -1665,9 +1672,6 @@ def get_prev_round(round: db.Round) -> Optional[db.Round]:
     if prev_round is None:
         flash('Předchozí kolo nenalezeno', 'danger')
         return None
-    elif prev_round.level < round.level:
-        flash('Předchozí kolo se koná ve vyšší oblasti než toto kolo', 'danger')
-        return None
     return prev_round
 
 
diff --git a/mo/web/org_round.py b/mo/web/org_round.py
index fec02c9526278dd38cc13074b99ca62bdbca776e..9b10d069daea4ab6d6f49a396c21cc92cdc791eb 100644
--- a/mo/web/org_round.py
+++ b/mo/web/org_round.py
@@ -678,14 +678,19 @@ def org_round_create_contests(round_id: int):
     have_places_subq = (sess.query(db.Contest.place_id)
                             .filter_by(round=round))
 
-    new_places = (sess.query(db.Place)
-                      .select_from(db.Contest)
-                      .filter(db.Contest.round == prev_round)
-                      .join(db.RegionDescendant, db.RegionDescendant.descendant == db.Contest.place_id)
-                      .join(db.Place, db.Place.place_id == db.RegionDescendant.region)
-                      .filter(db.Place.level == round.level)
-                      .filter(db.Place.place_id.notin_(have_places_subq))
-                      .all())
+    new_places_q = sess.query(db.Place).select_from(db.Contest).filter(db.Contest.round == prev_round)
+    if prev_round.level >= round.level:
+        new_places_q = (new_places_q
+                        .join(db.RegionDescendant, db.RegionDescendant.descendant == db.Contest.place_id)
+                        .join(db.Place, db.Place.place_id == db.RegionDescendant.region))
+    else:
+        new_places_q = (new_places_q
+                        .join(db.RegionDescendant, db.RegionDescendant.region == db.Contest.place_id)
+                        .join(db.Place, db.Place.place_id == db.RegionDescendant.descendant))
+    new_places = (new_places_q
+                  .filter(db.Place.level == round.level)
+                  .filter(db.Place.place_id.notin_(have_places_subq))
+                  .all())
 
     form = CreateContestsForm()
     if form.validate_on_submit():