diff --git a/mo/imports.py b/mo/imports.py
index 72c7b7b3dc98fdff4878118727dd51225f15254a..6d92c8e7082c37b9edbedb5e2e3ce89f1eaeb0ae 100644
--- a/mo/imports.py
+++ b/mo/imports.py
@@ -228,6 +228,10 @@ class Import:
         if pts < 0:
             return self.error('Body nesmí být záporné')
 
+        assert self.task is not None
+        if self.task.max_points is not None and pts > self.task.max_points:
+            return self.error(f'Body převyšují maximální počet bodů pro tuto úlohu ({self.task.max_points})')
+
         return pts
 
     def find_or_create_participant(self, user: db.User, year: int, school_id: int, birth_year: int, grade: str) -> Optional[db.Participant]:
diff --git a/mo/web/org_contest.py b/mo/web/org_contest.py
index 468f29ef34100b722976056f144e6d2fded70c93..c54e3ebd4610eac490a6ecb41e807a63a1d4fe67 100644
--- a/mo/web/org_contest.py
+++ b/mo/web/org_contest.py
@@ -26,6 +26,7 @@ from mo.web.util import PagerForm
 from mo.web.table import CellCheckbox, Table, Row, Column, cell_pion_link, cell_place_link, cell_email_link
 import wtforms.validators as validators
 from wtforms.fields.html5 import IntegerField
+from wtforms.widgets.html5 import NumberInput
 
 
 class ImportForm(FlaskForm):
@@ -637,7 +638,7 @@ def get_solution_context(contest_id: int, user_id: Optional[int], task_id: Optio
 class SubmitForm(FlaskForm):
     note = wtforms.TextAreaField("Poznámka pro účastníka", description="Viditelná účastníkovi po uzavření kola")
     org_note = wtforms.TextAreaField("Interní poznámka", description="Viditelná jen organizátorům")
-    points = IntegerField('Body', description="Účastník po uzavření kola uvidí jen naposledy zadané body", render_kw={'min': 0}, validators=[validators.Optional()])
+    points = IntegerField('Body', description="Účastník po uzavření kola uvidí jen naposledy zadané body", validators=[validators.Optional()])
     submit = wtforms.SubmitField('Uložit')
 
     file = flask_wtf.file.FileField("Soubor")
@@ -715,6 +716,11 @@ def org_submit_list(contest_id: int, user_id: int, task_id: int, site_id: Option
             return redirect(self_url)
 
     form = SubmitForm(obj=sol)
+    form.points.validators = [
+        validators.Optional(),
+        validators.NumberRange(min=0, max=sc.task.max_points, message="Počet bodů musí být mezi %(min)s a %(max)s")
+    ]
+    form.points.widget = NumberInput(min=0, max=sc.task.max_points)  # min a max v HTML
     if form.validate_on_submit():
         if sol and form.delete.data:
             if sol.final_submit or sol.final_feedback:
@@ -736,9 +742,6 @@ def org_submit_list(contest_id: int, user_id: int, task_id: int, site_id: Option
 
         points = form.points.data
         # Checks
-        if sol and sc.allow_edit_points and points and points < 0:
-            flash('Nelze zadat záporné body, žádné změny nebyly uloženy', 'danger')
-            return redirect(self_url)
         if (form.submit_sol.data or form.submit_fb.data) and form.file.data is None:
             flash('Schází soubor k nahrání, žádné změny nebyly uloženy', 'danger')
             return redirect(self_url)
@@ -982,6 +985,10 @@ def org_contest_task(contest_id: int, task_id: int, site_id: Optional[int] = Non
                     flash('Nelze zadat záporné body', 'danger')
                     ok = False
                     break
+                elif points and sc.task.max_points is not None and points > sc.task.max_points:
+                    flash(f'Maximální počet bodů za úlohu je {sc.task.max_points}, nelze zadat více', 'danger')
+                    ok = False
+                    break
 
                 if points != sol.points:
                     # Save points
diff --git a/mo/web/templates/parts/org_solution_table.html b/mo/web/templates/parts/org_solution_table.html
index 150d77ecb0f50d4af978c31b7e65e4557fa9c949..a9340f07d23895a0acdda8be4bfe5ef4d86cf693 100644
--- a/mo/web/templates/parts/org_solution_table.html
+++ b/mo/web/templates/parts/org_solution_table.html
@@ -85,7 +85,7 @@ finální (ve výchozím stavu poslední nahrané).{% elif sc.allow_upload_solut
 			{% if sol.org_note %} <span class="icon" title="Interní poznámka: {{ sol.org_note }}">🗩</span>{% endif %}
 		<td>
 			{% if points_form %}
-				<input type="number" class="form-control" name="points_{{u.user_id}}" value="{{ request_form.get("points_{}".format(u.user_id)) or sol.points }}" size="4">
+				<input type="number" min=0 {% if task.max_points is not none %}max={{ task.max_points }}{% endif %} class="form-control" name="points_{{u.user_id}}" value="{{ request_form.get("points_{}".format(u.user_id)) or sol.points }}" size="4">
 			{% else %}
 				{% if sol.points is not none %}{{ sol.points}}{% else %}<span class="unknown">?</span>{% endif %}
 			{% endif %}