diff --git a/README.md b/README.md
index 7e97af05a8819a0475cadd30de68e58dbf9f9da9..94e9f785bcce651621e3b26e9b4ce420cdce2562 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,9 @@ Work in progress competitive programming judge that is compatible with Polygon p
 ## How to Run
 
 * Make sure the `isolate/` submodule has been fetched
-* Just use docker compose (`docker-compose up`), there is a development environment
+* Copy `isolate/systemd/*` files to `/etc/systemd/system/` and start isolate's
+daemon that provides the base cgroups v2 root directory.
+* Use docker compose (`docker compose up`), there is a development environment
 and a production environment.
 
 ## Features
diff --git a/alvokanto/Dockerfile b/alvokanto/Dockerfile
index 40ecdc60db164d856aa07ceba6465d5f08f09262..1ed1d967d1f1ddc80e106c6cd6e8a5d3edb3fa76 100644
--- a/alvokanto/Dockerfile
+++ b/alvokanto/Dockerfile
@@ -46,8 +46,7 @@ RUN apt-get update && \
     rm -rf /var/lib/apt/lists/*
 COPY --from=isolate_builder /usr/local/bin/isolate /usr/local/bin/
 COPY --from=isolate_builder /usr/local/bin/isolate-check-environment /usr/local/bin/
-COPY --from=isolate_builder /usr/local/sbin/isolate-cg-keeper /usr/local/sbin/
-COPY --from=isolate_builder /usr/local/etc/isolate /usr/local/etc/isolate
+ADD alvokanto/isolate.cf /usr/local/etc/isolate
 COPY --from=builder /usr/local/bin/alvokanto /usr/local/bin/
 RUN mkdir -p /var/local/lib/isolate
 RUN mkdir -p /usr/local/alvokanto
diff --git a/alvokanto/dev.Dockerfile b/alvokanto/dev.Dockerfile
index 5231a9545a921998d783d17b071051b0f011268b..9f2252d24c4f260c07b973bf0557b41d683976ec 100644
--- a/alvokanto/dev.Dockerfile
+++ b/alvokanto/dev.Dockerfile
@@ -31,8 +31,7 @@ RUN apt-get update && \
 RUN rustup component add rustfmt
 COPY --from=isolate_builder /usr/local/bin/isolate /usr/local/bin/
 COPY --from=isolate_builder /usr/local/bin/isolate-check-environment /usr/local/bin/
-COPY --from=isolate_builder /usr/local/sbin/isolate-cg-keeper /usr/local/sbin/
-COPY --from=isolate_builder /usr/local/etc/isolate /usr/local/etc/isolate
+ADD alvokanto/isolate.cf /usr/local/etc/isolate
 RUN mkdir -p /var/local/lib/isolate
 RUN --mount=type=cache,target=/usr/local/cargo/registry \
     --mount=type=cache,target=/usr/local/cargo/git \
diff --git a/alvokanto/isolate.cf b/alvokanto/isolate.cf
new file mode 100644
index 0000000000000000000000000000000000000000..6556fa9b1f76e69b9dcf9cfc88958d50204ebc1c
--- /dev/null
+++ b/alvokanto/isolate.cf
@@ -0,0 +1,29 @@
+# This is a configuration file for Isolate
+
+# All sandboxes are created under this directory.
+# To avoid symlink attacks, this directory and all its ancestors
+# must be writeable only to root.
+box_root = /var/local/lib/isolate
+
+# Directory where lock files are created.
+lock_root = /run/isolate/locks
+
+# Control group under which we place our subgroups
+# Either an explicit path to a subdirectory in cgroupfs, or "auto:file" to read
+# the path from "file", where it is put by isolate-cg-helper.
+cg_root = /sys/fs/cgroup/isolate.slice/isolate.service
+# cg_root = auto:/run/isolate/cgroup
+
+# Block of UIDs and GIDs reserved for sandboxes
+first_uid = 60000
+first_gid = 60000
+num_boxes = 1000
+
+# Only root can create new sandboxes (default: 0=everybody can)
+#restricted_init = 1
+
+# Per-box settings of the set of allowed CPUs and NUMA nodes
+# (see linux/Documentation/cgroups/cpusets.txt for precise syntax)
+
+#box0.cpus = 4-7
+#box0.mems = 1
diff --git a/alvokanto/src/isolate.rs b/alvokanto/src/isolate.rs
index c600a2075f34d3593dcc291242737f4fe39b7185..2cfe869cce94698d4d8cbd146f9cf02bfc4db3a1 100644
--- a/alvokanto/src/isolate.rs
+++ b/alvokanto/src/isolate.rs
@@ -28,13 +28,8 @@ pub struct IsolateBox {
 
 pub fn new_isolate_box(
     isolate_executable_path: &PathBuf,
-    isolate_cg_keeper_path: &PathBuf,
     id: i32,
 ) -> Result<IsolateBox, CommandError> {
-    Command::new(isolate_cg_keeper_path)
-        .spawn()
-        .map_err(CommandError::CommandIo)?;
-
     let output = reset(isolate_executable_path, id)?;
     Ok(IsolateBox {
         id,
@@ -46,8 +41,6 @@ pub fn reset(
     isolate_executable_path: &PathBuf,
     id: i32,
 ) -> Result<std::process::Output, CommandError> {
-    cleanup_box(isolate_executable_path, id)?;
-
     let output = Command::new(isolate_executable_path)
         .arg("--init")
         .arg("--cg")
@@ -61,6 +54,8 @@ pub fn reset(
         ));
     }
 
+    info!("Resetting box {}: {}", id, str::from_utf8(&output.stdout)?);
+
     Ok(output)
 }
 
@@ -319,14 +314,3 @@ pub fn compile(
         },
     )
 }
-
-pub fn cleanup_box(isolate_executable_path: &PathBuf, box_id: i32) -> Result<bool, CommandError> {
-    Ok(Command::new(isolate_executable_path)
-        .arg("--cleanup")
-        .arg("--cg")
-        .arg(format!("--box-id={}", box_id))
-        .output()
-        .map_err(CommandError::CommandIo)?
-        .status
-        .success())
-}
diff --git a/alvokanto/src/main.rs b/alvokanto/src/main.rs
index 5dbf737478216c8f189fe797aba31455257cd459..c58e50d0e1deb7180f0eaaef51dafd5e59c0206a 100644
--- a/alvokanto/src/main.rs
+++ b/alvokanto/src/main.rs
@@ -14,6 +14,7 @@ mod language;
 use tokio::time::{sleep, Duration};
 use isolate::{IsolateBox, new_isolate_box, RunStatus, RunStats, CommandTuple, CompileParams};
 use std::fs::read_to_string;
+use std::os::unix::fs::PermissionsExt;
 use std::fs;
 use log::info;
 use language::Compile;
@@ -25,10 +26,6 @@ pub fn get_isolate_executable_path() -> PathBuf {
     which("isolate").expect("isolate binary not installed")
 }
 
-pub fn get_isolate_cg_keeper_executable_path() -> PathBuf {
-    which("isolate-cg-keeper").expect("isolate-cg-keeper binary not installed")
-}
-
 fn run_cached(
     isolate_executable_path: &PathBuf,
     isolate_box: &IsolateBox,
@@ -61,7 +58,7 @@ fn run_cached(
                 .replace("{}", path_without_suffix.to_str().unwrap());
         if !root_data.join(&output_path).exists() {
             isolate::reset(&isolate_executable_path, isolate_box.id)
-                .expect("reset to work");
+                .expect("Reset failed");
             fs_extra::dir::copy(
                 path_with_suffix.parent().unwrap(),
                 &isolate_box.path,
@@ -148,6 +145,8 @@ fn run_cached(
             .collect(),
     };
 
+    isolate::reset(&isolate_executable_path, isolate_box.id)
+        .expect("Reset failed");
     let run_stats = isolate::execute(
         &isolate_executable_path,
         &isolate_box,
@@ -167,9 +166,6 @@ fn run_cached(
 
     let error_output = read_to_string(run_stats.stderr_path).unwrap_or("".into());
 
-    isolate::reset(&isolate_executable_path, isolate_box.id)
-        .expect("reset to work");
-
     JobResult {
         uuid,
         code: job_result::Code::Ok.into(),
@@ -194,41 +190,27 @@ fn run_cached(
     }
 }
 
-fn judge(
+fn compile_checker_if_necessary(
     isolate_executable_path: &PathBuf,
     isolate_box: &IsolateBox,
     supported_languages: &HashMap<String, language::LanguageParams>,
-    uuid: String,
-    language: String,
-    time_limit_ms: i32,
-    memory_limit_kib: i32,
-    request: job::Judgement
-) -> JobResult {
+    uuid: &String,
+    request: &job::Judgement
+) -> Option<JobResult> {
     let root_data = PathBuf::from("/data/");
 
-    let language = supported_languages.get(&language);
-    if let None = language {
-        return JobResult {
-            uuid,
-            code: job_result::Code::InvalidLanguage.into(),
-            which: None,
-        };
-    }
-    let language = language.unwrap();
-
     let checker_language = supported_languages.get(&request.checker_language);
     if let None = checker_language {
-        return JobResult {
-            uuid,
+        return Some(JobResult {
+            uuid: uuid.to_string(),
             code: job_result::Code::InvalidLanguage.into(),
             which: None,
-        };
+        });
     }
     let checker_language = checker_language.unwrap();
 
     let path_with_suffix = PathBuf::from("/data/").join(&request.checker_source_path);
     let path_without_suffix = path_with_suffix.with_extension("");
-
     if let Compile::Command(_, command, output) = &checker_language.compile {
         let output_path =
             output.replace("{.}", path_with_suffix.to_str().unwrap())
@@ -284,8 +266,8 @@ fn judge(
                 } => true,
             } {
                 fs_extra::dir::create(&isolate_box.path, true).unwrap();
-                return JobResult {
-                    uuid,
+                return Some(JobResult {
+                    uuid: uuid.to_string(),
                     code: job_result::Code::Ok.into(),
                     which: Some(job_result::Which::Judgement(job_result::Judgement {
                         failed_test: 0,
@@ -299,7 +281,7 @@ fn judge(
                         judge_start_instant: Local::now().naive_utc().format("%Y-%m-%dT%H:%M:%S%.f").to_string(),
                         judge_end_instant: Local::now().naive_utc().format("%Y-%m-%dT%H:%M:%S%.f").to_string(),
                     }))
-                }
+                })
             }
 
             fs::copy(&isolate_box.path.join(
@@ -308,15 +290,51 @@ fn judge(
         }
     }
 
+    return None
+}
+
+fn judge(
+    isolate_executable_path: &PathBuf,
+    isolate_box: &IsolateBox,
+    supported_languages: &HashMap<String, language::LanguageParams>,
+    uuid: String,
+    language: String,
+    time_limit_ms: i32,
+    memory_limit_kib: i32,
+    request: job::Judgement
+) -> JobResult {
+    let language = supported_languages.get(&language);
+    if let None = language {
+        return JobResult {
+            uuid,
+            code: job_result::Code::InvalidLanguage.into(),
+            which: None,
+        };
+    }
+    let language = language.unwrap();
+
+    if let Some(res) = compile_checker_if_necessary(
+        isolate_executable_path,
+        isolate_box,
+        supported_languages,
+        &uuid,
+        &request
+    ) {
+        return res
+    }
+
     let judge_start_instant = Local::now().naive_utc();
 
+    let mut binary_file = request.source_text.as_bytes().to_vec();
+
     if let Compile::Command(transform, command, _) = &language.compile {
         isolate::reset(&isolate_executable_path, isolate_box.id)
-            .expect("reset to work");
+            .expect("Reset failed");
 
-        let mut file = File::create(isolate_box.path.join(format!("x{}", language.suffix))).unwrap();
-        file.write_all(transform(request.source_text, "x".into()).as_bytes()).unwrap();
-        file.sync_data().unwrap();
+        {
+            let mut file = File::create(isolate_box.path.join(format!("x{}", language.suffix))).unwrap();
+            file.write_all(transform(request.source_text, "x".into()).as_bytes()).unwrap();
+        }
 
         let command = CommandTuple {
             binary_path: command.binary_path.clone(),
@@ -371,10 +389,10 @@ fn judge(
                 }))
             }
         }
-    } else {
-        let mut file = File::create(isolate_box.path.join(format!("x{}", language.suffix))).unwrap();
-        file.write_all(request.source_text.as_bytes()).unwrap();
-        file.sync_data().unwrap();
+
+        binary_file = fs::read(isolate_box.path.join(language.run.binary_path.to_str().unwrap()
+            .replace("{.}", &format!("x{}", language.suffix))
+            .replace("{}", "x".into()))).unwrap();
     }
 
     let mut last_execute_stats: Option<RunStats> = None;
@@ -399,6 +417,8 @@ fn judge(
     let mut time_wall_ms = 0;
 
     for i in 1..request.test_count + 1 {
+        isolate::reset(&isolate_executable_path, isolate_box.id)
+            .expect("Reset failed");
         let stdin_path =
             format_width(&request.test_pattern, i.try_into().unwrap());
         let answer_path = format!("{}.a", stdin_path);
@@ -406,6 +426,13 @@ fn judge(
             "Starting run {}/{} with test {:?}",
             i, request.test_count, stdin_path
         );
+        {
+            let mut file = File::create(isolate_box.path.join(&command.binary_path)).unwrap();
+            let mut perms = file.metadata().unwrap().permissions();
+            perms.set_mode(0o755);
+            file.set_permissions(perms).unwrap();
+            file.write_all(&binary_file).unwrap();
+        }
         let execute_stats = isolate::execute(
             &isolate_executable_path,
             &isolate_box,
@@ -492,9 +519,6 @@ fn judge(
         }
     }
 
-    isolate::reset(&isolate_executable_path, isolate_box.id)
-        .expect("reset to work");
-
     let judge_end_instant = Local::now().naive_utc();
 
     let last_execute_stats = last_execute_stats.unwrap();
@@ -584,10 +608,8 @@ async fn main() {
     env_logger::init();
 
     let isolate_executable_path = get_isolate_executable_path();
-    let isolate_cg_keeper_executable_path = get_isolate_cg_keeper_executable_path();
     log::info!("Found isolate at {:?}", isolate_executable_path);
-    log::info!("Found isolate-cg-keeper at {:?}", isolate_cg_keeper_executable_path);
-    let isolate_box = new_isolate_box(&isolate_executable_path, &isolate_cg_keeper_executable_path, 0).expect("Couldn't create an isolate box");
+    let isolate_box = new_isolate_box(&isolate_executable_path, 0).expect("Couldn't create an isolate box");
     log::info!("Created an isolate box at {:?}", isolate_box.path);
 
     let supported_languages = language::get_supported_languages();
diff --git a/alvokanto/src/queue.rs b/alvokanto/src/queue.rs
index 50a8ecffc2c1e52496962d8a96c909cf852e6776..d9e1343529567770738e5ca7bcf237cf8acc168e 100644
--- a/alvokanto/src/queue.rs
+++ b/alvokanto/src/queue.rs
@@ -46,6 +46,7 @@ fn run_loop(
 
         info!("Starting to compile");
         let language = languages.get(&submission.language).unwrap();
+        isolate::reset(isolate_executable_path, 0).expect("Reset failed");
         let compile_source_result = language::compile_source(
             &isolate_executable_path,
             &isolate_box,
@@ -107,6 +108,7 @@ fn run_loop(
                 "Starting run {}/{} with test {:?}",
                 i, submission.test_count, stdin_path
             );
+            isolate::reset(isolate_executable_path, 0).expect("Reset failed");
             let execute_stats = language::run(
                 &isolate_executable_path,
                 &isolate_box,
@@ -143,6 +145,7 @@ fn run_loop(
 
             fs::copy(&execute_stats.stdout_path, isolate_box.path.join("stdin")).expect("Copy");
 
+            isolate::reset(isolate_executable_path, 0).expect("Reset failed");
             let checker_stats = isolate::execute(
                 &isolate_executable_path,
                 &isolate_box,
@@ -205,8 +208,6 @@ fn run_loop(
 
         let last_execute_stats = last_execute_stats.unwrap();
 
-        isolate::reset(isolate_executable_path, 0).expect("Reset failed");
-
         if let(last_execute_stats.status) = RunStatus::TimeLimitExceeded {
             if last_execute_stats.time_ms == 0 { continue; }
         }
@@ -231,7 +232,9 @@ fn run_loop(
                 time_wall_ms: last_execute_stats.time_wall_ms,
                 error_output: stderr,
             })
-            .expect("Coudln't send back submission completion");
+            .expect("Couldn't send back submission completion");
+
+        break;
     }
 }
 
diff --git a/docker-compose.yml b/docker-compose.yml
index 4d2a4cc08f06753dd076e024f24a652c631ff9e2..9a4c9eed71f74b04bfd8c01ef23fb04a560266c2 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -13,4 +13,8 @@ services:
     build:
       context: .
       dockerfile: alvokanto/Dockerfile
+    volumes:
+      - type: bind
+        source: /sys/fs/cgroup/isolate.slice
+        target: /sys/fs/cgroup/isolate.slice
     privileged: true
diff --git a/src/import_contest.rs b/src/import_contest.rs
index ddc42ff281de239c4798dbdff98ccca47845577c..cde9b7de5a0c535f36623ae3d4b4ba9c30ffd568 100644
--- a/src/import_contest.rs
+++ b/src/import_contest.rs
@@ -51,6 +51,7 @@ mod xml {
 
         #[derive(Deserialize, Debug)]
         pub struct Contest {
+            #[serde(rename = "@url")]
             pub url: String,
             pub names: Names,
             pub problems: Problems,
@@ -63,7 +64,9 @@ mod xml {
 
         #[derive(Deserialize, Debug)]
         pub struct Name {
+            #[serde(rename = "@language")]
             pub language: String,
+            #[serde(rename = "@value")]
             pub value: String,
         }
 
@@ -74,7 +77,9 @@ mod xml {
 
         #[derive(Deserialize, Debug)]
         pub struct Problem {
+            #[serde(rename = "@index")]
             pub index: String,
+            #[serde(rename = "@url")]
             pub url: String,
         }
 
@@ -90,9 +95,11 @@ mod xml {
 
         #[derive(Deserialize, Debug)]
         pub struct Problem {
+            #[serde(rename = "@url")]
             pub url: String,
+            #[serde(rename = "@revision")]
             pub revision: String,
-            #[serde(rename = "short-name")]
+            #[serde(rename = "@short-name")]
             pub short_name: String,
             pub names: Names,
             pub statements: Statements,
@@ -110,7 +117,9 @@ mod xml {
 
         #[derive(Deserialize, Debug)]
         pub struct Name {
+            #[serde(rename = "@language")]
             pub language: String,
+            #[serde(rename = "@value")]
             pub value: String,
         }
 
@@ -121,72 +130,48 @@ mod xml {
 
         #[derive(Deserialize, Debug)]
         pub struct Statement {
+            #[serde(rename = "@charset")]
             pub charset: Option<String>,
+            #[serde(rename = "@language")]
             pub language: String,
+            #[serde(rename = "@mathjax")]
             pub mathjax: Option<bool>,
+            #[serde(rename = "@path")]
             pub path: String,
+            #[serde(rename = "@type")]
             pub r#type: String,
         }
 
         #[derive(Deserialize, Debug)]
         pub struct Judging {
-            #[serde(rename = "cpu-name")]
+            #[serde(rename = "@cpu-name")]
             pub cpu_name: String,
-            #[serde(rename = "cpu-speed")]
+            #[serde(rename = "@cpu-speed")]
             pub cpu_speed: String,
-            #[serde(rename = "input-file")]
+            #[serde(rename = "@input-file")]
             pub input_file: String,
-            #[serde(rename = "output-file")]
+            #[serde(rename = "@output-file")]
             pub output_file: String,
             pub testset: Vec<Testset>,
         }
 
         #[derive(Deserialize, Debug)]
         pub struct Testset {
+            #[serde(rename = "@name")]
             pub name: String,
             #[serde(rename = "time-limit")]
-            pub time_limit: TimeLimit,
+            pub time_limit: String,
             #[serde(rename = "memory-limit")]
-            pub memory_limit: MemoryLimit,
+            pub memory_limit: String,
             #[serde(rename = "test-count")]
-            pub test_count: TestCount,
+            pub test_count: String,
             #[serde(rename = "input-path-pattern")]
-            pub input_path_pattern: InputPathPattern,
+            pub input_path_pattern: String,
             #[serde(rename = "answer-path-pattern")]
-            pub answer_path_pattern: AnswerPathPattern,
+            pub answer_path_pattern: String,
             pub tests: Tests,
         }
 
-        #[derive(Deserialize, Debug)]
-        pub struct TimeLimit {
-            #[serde(rename = "$value")]
-            pub value: String,
-        }
-
-        #[derive(Deserialize, Debug)]
-        pub struct MemoryLimit {
-            #[serde(rename = "$value")]
-            pub value: String,
-        }
-
-        #[derive(Deserialize, Debug)]
-        pub struct TestCount {
-            #[serde(rename = "$value")]
-            pub value: String,
-        }
-
-        #[derive(Deserialize, Debug)]
-        pub struct InputPathPattern {
-            #[serde(rename = "$value")]
-            pub value: String,
-        }
-
-        #[derive(Deserialize, Debug)]
-        pub struct AnswerPathPattern {
-            #[serde(rename = "$value")]
-            pub value: String,
-        }
-
         #[derive(Deserialize, Debug)]
         pub struct Tests {
             pub test: Vec<Test>,
@@ -194,9 +179,13 @@ mod xml {
 
         #[derive(Deserialize, Debug)]
         pub struct Test {
+            #[serde(rename = "@method")]
             pub method: Option<String>,
+            #[serde(rename = "@sample")]
             pub sample: Option<bool>,
+            #[serde(rename = "@description")]
             pub description: Option<String>,
+            #[serde(rename = "@cmd")]
             pub cmd: Option<String>,
         }
 
@@ -213,6 +202,7 @@ mod xml {
 
         #[derive(Deserialize, Debug)]
         pub struct File {
+            #[serde(rename = "@path")]
             pub path: String,
         }
 
@@ -229,13 +219,17 @@ mod xml {
 
         #[derive(Deserialize, Debug)]
         pub struct Source {
+            #[serde(rename = "@path")]
             pub path: String,
+            #[serde(rename = "@type")]
             pub r#type: String,
         }
 
         #[derive(Deserialize, Debug)]
         pub struct Binary {
+            #[serde(rename = "@path")]
             pub path: String,
+            #[serde(rename = "@type")]
             pub r#type: String,
         }
 
@@ -248,6 +242,7 @@ mod xml {
 
         #[derive(Deserialize, Debug)]
         pub struct Checker {
+            #[serde(rename = "@type")]
             pub r#type: String,
             pub source: Source,
             pub binary: Binary,
@@ -258,16 +253,17 @@ mod xml {
         #[derive(Deserialize, Debug)]
         pub struct CheckerTestset {
             #[serde(rename = "test-count")]
-            pub test_count: TestCount,
+            pub test_count: String,
             #[serde(rename = "input-path-pattern")]
-            pub input_path_pattern: InputPathPattern,
+            pub input_path_pattern: String,
             #[serde(rename = "answer-path-pattern")]
-            pub answer_path_pattern: AnswerPathPattern,
+            pub answer_path_pattern: String,
             pub tests: VerdictTests,
         }
 
         #[derive(Deserialize, Debug)]
         pub struct Copy {
+            #[serde(rename = "@path")]
             pub path: String,
         }
 
@@ -286,9 +282,9 @@ mod xml {
         #[derive(Deserialize, Debug)]
         pub struct ValidatorTestset {
             #[serde(rename = "test-count")]
-            pub test_count: TestCount,
+            pub test_count: String,
             #[serde(rename = "input-path-pattern")]
-            pub input_path_pattern: InputPathPattern,
+            pub input_path_pattern: String,
             pub tests: VerdictTests,
         }
 
@@ -299,6 +295,7 @@ mod xml {
 
         #[derive(Deserialize, Debug)]
         pub struct VerdictTest {
+            #[serde(rename = "@verdict")]
             pub verdict: String,
         }
 
@@ -309,6 +306,7 @@ mod xml {
 
         #[derive(Deserialize, Debug)]
         pub struct Solution {
+            #[serde(rename = "@tag")]
             pub tag: String,
             pub source: Source,
             pub binary: Binary,
@@ -321,7 +319,9 @@ mod xml {
 
         #[derive(Deserialize, Debug)]
         pub struct Property {
+            #[serde(rename = "@name")]
             pub name: String,
+            #[serde(rename = "@value")]
             pub value: String,
         }
 
@@ -344,6 +344,7 @@ mod xml {
 
         #[derive(Deserialize, Debug)]
         pub struct Tag {
+            #[serde(rename = "@value")]
             pub value: String,
         }
 
diff --git a/src/pages/create_contest.rs b/src/pages/create_contest.rs
index 8d79f0e3f15888ad18af8dd4f1fa12a96c238a18..ef82d8fc0c5d6d171f3afca37709a82c316fd778 100644
--- a/src/pages/create_contest.rs
+++ b/src/pages/create_contest.rs
@@ -145,6 +145,7 @@ async fn create_contest(
             m.insert("cpp.g++17".into(), "cpp.17.g++".into());
             m.insert("cpp.g++20".into(), "cpp.20.g++".into());
             m.insert("cpp.msys2-mingw64-9-g++17".into(), "cpp.17.g++".into());
+            m.insert("cpp.msys2-mingw64-9-g++20".into(), "cpp.20.g++".into());
             m.insert("java.8".into(), "java.8".into());
             m.insert("testlib".into(), "cpp.20.g++".into());
             m
@@ -224,12 +225,10 @@ async fn create_contest(
                 name: metadata.names.name[0].value.clone(),
                 memory_limit_bytes: metadata.judging.testset[0]
                     .memory_limit
-                    .value
                     .parse()
                     .unwrap(),
                 time_limit_ms: metadata.judging.testset[0]
                     .time_limit
-                    .value
                     .parse()
                     .unwrap(),
                 checker_path: metadata.assets.checker.source.path.clone(),
@@ -240,10 +239,9 @@ async fn create_contest(
                 )?,
                 main_solution_path: main_solution.path.clone(),
                 main_solution_language: map_codeforces_language(&main_solution.r#type)?,
-                test_pattern: metadata.judging.testset[0].input_path_pattern.value.clone(),
+                test_pattern: metadata.judging.testset[0].input_path_pattern.clone(),
                 test_count: metadata.judging.testset[0]
                     .test_count
-                    .value
                     .parse()
                     .unwrap(),
                 status: "compiled".into(),