diff --git a/.github/classroom/autograding.json b/.github/classroom/autograding.json
new file mode 100644
index 0000000..ebad661
--- /dev/null
+++ b/.github/classroom/autograding.json
@@ -0,0 +1,44 @@
+{
+  "tests": [
+    {
+      "name": "Test 1",
+      "setup": "",
+      "run": "dotnet test --filter TestCategory=1",
+      "input": "",
+      "output": "",
+      "comparison": "exact",
+      "timeout": 1,
+      "points": 3
+    },
+    {
+      "name": "Test 2",
+      "setup": "",
+      "run": "dotnet test --filter TestCategory=2",
+      "input": "",
+      "output": "",
+      "comparison": "exact",
+      "timeout": 1,
+      "points": 2
+    },
+    {
+      "name": "Test 3",
+      "setup": "",
+      "run": "dotnet test --filter TestCategory=3",
+      "input": "",
+      "output": "",
+      "comparison": "exact",
+      "timeout": 1,
+      "points": 3
+    },
+    {
+      "name": "Test 4",
+      "setup": "",
+      "run": "dotnet test --filter TestCategory=4",
+      "input": "",
+      "output": "",
+      "comparison": "exact",
+      "timeout": 1,
+      "points": 2
+    }
+  ]
+}
diff --git a/.github/workflows/classroom.yml b/.github/workflows/classroom.yml
new file mode 100644
index 0000000..a4dc534
--- /dev/null
+++ b/.github/workflows/classroom.yml
@@ -0,0 +1,19 @@
+name: GitHub Classroom Workflow
+
+on:
+  - push
+  - workflow_dispatch
+
+permissions:
+  checks: write
+  actions: read
+  contents: read
+
+jobs:
+  build:
+    name: Autograding
+    runs-on: ubuntu-latest
+    if: github.actor != 'github-classroom[bot]' && github.actor != 'sangkilc'
+    steps:
+      - uses: actions/checkout@v4
+      - uses: education/autograding@v1
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4eb29fe
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+[Dd]ebug/
+[Rr]elease/
+[Bb]in/
+[Oo]bj/
+
+.vscode
+.vs/
+.DS_Store
diff --git a/Homework1.fsproj b/Homework1.fsproj
new file mode 100644
index 0000000..5a3c697
--- /dev/null
+++ b/Homework1.fsproj
@@ -0,0 +1,12 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net8.0</TargetFramework>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <Compile Include="Program.fs" />
+  </ItemGroup>
+
+</Project>
diff --git a/Homework1.sln b/Homework1.sln
new file mode 100644
index 0000000..8697e09
--- /dev/null
+++ b/Homework1.sln
@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31903.59
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Homework1", "Homework1.fsproj", "{E719E6F5-32C4-4F65-842F-4DD030EAAB7C}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Tests", "Tests\Tests.fsproj", "{2935EE11-D675-4545-BA6A-9DD6EF124B6B}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{E719E6F5-32C4-4F65-842F-4DD030EAAB7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E719E6F5-32C4-4F65-842F-4DD030EAAB7C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E719E6F5-32C4-4F65-842F-4DD030EAAB7C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E719E6F5-32C4-4F65-842F-4DD030EAAB7C}.Release|Any CPU.Build.0 = Release|Any CPU
+		{2935EE11-D675-4545-BA6A-9DD6EF124B6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{2935EE11-D675-4545-BA6A-9DD6EF124B6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{2935EE11-D675-4545-BA6A-9DD6EF124B6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{2935EE11-D675-4545-BA6A-9DD6EF124B6B}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+EndGlobal
diff --git a/Program.fs b/Program.fs
new file mode 100644
index 0000000..ed5e951
--- /dev/null
+++ b/Program.fs
@@ -0,0 +1,41 @@
+module CS220.Program
+
+/// Define a function `prob1` that takes in three (int) numbers as input and
+/// returns the sum of the squares of the two large numbers. If there is any
+/// error in processing the inputs, e.g., integer overflows, then the function
+/// should simply return -1 (do not raise an exception).
+let prob1 a b c =
+  failwith "TODO"
+
+/// Define a function `prob2` that takes in a string and returns a new string
+/// that ends with a newline character '\n'. The function appends a newline
+/// character to the given string only if the string does not already end with a
+/// newline character. Note that a string in F# is indeed, an array of
+/// characters, and each character in a string can be accessed through an item
+/// accessor. For example, str[0] returns the first character of the string str.
+/// Also, one can get the length of a string s by calling a function
+/// String.length: String.length s returns the length of the string s. Finally,
+/// you can append two strings using the + operator.
+let prob2 (str: string) =
+  failwith "TODO"
+
+/// Write a function `prob3` that takes in as input three floating point numbers
+/// a, b, and c, and returns a root of the quadratic formula $ax^2 + bx + c =
+/// 0$. If there are two roots, then the function should return the bigger root.
+/// If there is only one root, then the function should return the root. If
+/// there are no real roots, then the function should return nan, which is a
+/// special floating point number representing "Not a Number".
+let prob3 a b c =
+  failwith "TODO"
+
+/// Define a function `prob4` that returns the number of days in a month. The
+/// function takes in as input an integer representing a month, and outputs the
+/// number of days. You can assume that February has 28 days. The function
+/// returns -1 for any error cases. For example, if a number big than 12 is
+/// given as input, then the function should return -1.
+let prob4 month =
+  failwith "TODO"
+
+[<EntryPoint>]
+let main _args =
+  0
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..92ca532
--- /dev/null
+++ b/README.md
@@ -0,0 +1,85 @@
+CS220 - HW1
+===
+
+## Build?
+
+You can compile the project by typing `dotnet build`.
+
+## Test?
+
+You can test your implementation by typing `dotnet test`. If you can pass
+all the tests, you should be good to commit and push your code.
+
+## Structure
+
+- `Program.fs`: The main entry point of the project.
+- `Tests/Tests.fs`: The test suite for the project.
+- `HomeworkX.fsproj`: The F# project file for the project, where `X` is the
+  homework number.
+
+## Problems
+
+You should read the fsproj file and read the relevant source files to understand
+the problems. Typically, we will provide an empty (or partial) implementation
+for you to fill in where you can find some comments describing the problem. Of
+course, you can also read the relevant test cases to understand the problem.
+
+## Submission
+
+You are given a GitHub classroom link to start the assignment, which will
+automatically create a private repository for you. If your repository URL
+contains your GitHub username, then you are in the right place. If not, please
+get your own private repository from the GitHub classroom link.
+
+You should make modification to your own repository to finish your homework.
+Again, your own repository is only visible to you and the course staff. Plus,
+your repository URL should contain your GitHub username. You should commit and
+push your code to your own repository in order to get a grade.
+
+Whenever you push your code to your repository, the GitHub classroom workflow
+will automatically run the test cases and give you a grade based on the test
+results. You can check the test results by clicking the "Actions" tab in your
+repository page.
+
+If you see a red cross in the "Actions" tab, it means that some of the test
+cases are failing. You should check the test results to understand why the test
+cases are failing. If you see a green check, it means that all the test cases
+are passing, and you should be good to go.
+
+You can always make another commit to fix problems in your implementation, and
+push the changes to the repository. The GitHub classroom workflow will
+re-evaluate your implementation and update your grade.
+
+## Failure from the Workflow?
+
+Don't panic if you see a red cross in the "Actions" tab. You can always make
+another commit to fix problems in your implementation, and push the changes to
+the repository. The GitHub classroom workflow will re-evaluate your
+implementation and update your grade automatically.
+
+## Auto-Grading?
+
+Auto-grading is performed via the GitHub classroom workflow, which is defined in
+`.github/workflows/classroom.yml`. The workflow basically runs `dotnet test` to
+test your implementation and then gives you a grade based on the test results.
+If you can pass all the tests in your local environment, you should be able to
+get a full score.
+
+## Cheating Policy
+
+One may exploit the automatic grading system by hardcoding the expected result
+in the test cases --- that is, one can simply add if-then-else statements in the
+program to pass all the tests. But, we consider this attempt as cheating.
+
+If we detect any cheating attempt (including but not limited to the one above),
+we will immediately give you an F grade for the course, and report the case to
+the department.
+
+## Solutions?
+
+There is no single correct solution to the problems. You can always come up with
+your own solution as long as it can pass the test cases. If you have any
+questions about the problems, feel free to write an issue in the
+[main](https://github.com/KAIST-CS220/CS220-Main) repository. But please do
+search the existing issues to see if your question has already been answered
+before writing a new one.
\ No newline at end of file
diff --git a/Tests/Program.fs b/Tests/Program.fs
new file mode 100644
index 0000000..fdc31cd
--- /dev/null
+++ b/Tests/Program.fs
@@ -0,0 +1 @@
+module Program = let [<EntryPoint>] main _ = 0
diff --git a/Tests/Tests.fs b/Tests/Tests.fs
new file mode 100644
index 0000000..68fec71
--- /dev/null
+++ b/Tests/Tests.fs
@@ -0,0 +1,96 @@
+namespace CS220
+
+open Microsoft.VisualStudio.TestTools.UnitTesting
+
+[<TestClass>]
+type TestClass () =
+
+  [<TestMethod; Timeout 1000; TestCategory "1">]
+  member __.``Probem 1.A``() =
+    let r = Program.prob1 1 2 2
+    Assert.AreEqual (8, r)
+
+  [<TestMethod; Timeout 1000; TestCategory "1">]
+  member __.``Probem 1.B``() =
+    let r = Program.prob1 10 1 20
+    Assert.AreEqual (500, r)
+
+  [<TestMethod; Timeout 1000; TestCategory "1">]
+  member __.``Probem 1.C``() =
+    let r = Program.prob1 -1 -1 -1
+    Assert.AreEqual (2, r)
+
+  [<TestMethod; Timeout 1000; TestCategory "1">]
+  member __.``Probem 1.D``() =
+    let r = Program.prob1 0x12345 1 2
+    Assert.AreEqual (-1, r)
+
+  [<TestMethod; Timeout 1000; TestCategory "1">]
+  member __.``Probem 1.E``() =
+    let r = Program.prob1 -0x12345 -0x123456 0x42
+    Assert.AreEqual (-1, r)
+
+  [<TestMethod; Timeout 1000; TestCategory "1">]
+  member __.``Probem 1.F``() =
+    let r = Program.prob1 0xa000 0xd000 0x8000
+    Assert.AreEqual (-1, r)
+
+  [<TestMethod; Timeout 1000; TestCategory "2">]
+  member __.``Probem 2.A``() =
+    let r = Program.prob2 "AAA"
+    Assert.AreEqual ("AAA\n", r)
+
+  [<TestMethod; Timeout 1000; TestCategory "2">]
+  member __.``Probem 2.B``() =
+    let r = Program.prob2 ""
+    Assert.AreEqual ("\n", r)
+
+  [<TestMethod; Timeout 1000; TestCategory "3">]
+  member __.``Probem 3.A``() =
+    let r = Program.prob3 1.0 0.0 0.0
+    Assert.AreEqual (0.0, r)
+
+  [<TestMethod; Timeout 1000; TestCategory "3">]
+  member __.``Probem 3.B``() =
+    let r = Program.prob3 1.1 1.1 1.1
+    Assert.AreEqual (nan, r)
+
+  [<TestMethod; Timeout 1000; TestCategory "3">]
+  member __.``Probem 3.C``() =
+    let r = Program.prob3 1.0 2.0 1.0
+    Assert.AreEqual (-1.0, r, 0.0000001)
+
+  [<TestMethod; Timeout 1000; TestCategory "3">]
+  member __.``Probem 3.D``() =
+    let r = Program.prob3 0.0 0.0 2.0
+    Assert.AreEqual (nan, r)
+
+  [<TestMethod; Timeout 1000; TestCategory "3">]
+  member __.``Probem 3.E``() =
+    let r = Program.prob3 nan nan nan
+    Assert.AreEqual (nan, r)
+
+  [<TestMethod; Timeout 1000; TestCategory "4">]
+  member __.``Probem 4.A``() =
+    let r = Program.prob4 10
+    Assert.AreEqual (31, r)
+
+  [<TestMethod; Timeout 1000; TestCategory "4">]
+  member __.``Probem 4.B``() =
+    let r = Program.prob4 2
+    Assert.AreEqual (28, r)
+
+  [<TestMethod; Timeout 1000; TestCategory "4">]
+  member __.``Probem 4.C``() =
+    let r = Program.prob4 9
+    Assert.AreEqual (30, r)
+
+  [<TestMethod; Timeout 1000; TestCategory "4">]
+  member __.``Probem 4.D``() =
+    let r = Program.prob4 -1
+    Assert.AreEqual (-1, r)
+
+  [<TestMethod; Timeout 1000; TestCategory "4">]
+  member __.``Probem 4.E``() =
+    let r = Program.prob4 0
+    Assert.AreEqual (-1, r)
diff --git a/Tests/Tests.fsproj b/Tests/Tests.fsproj
new file mode 100644
index 0000000..b3da832
--- /dev/null
+++ b/Tests/Tests.fsproj
@@ -0,0 +1,27 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net8.0</TargetFramework>
+
+    <IsPackable>false</IsPackable>
+    <GenerateProgramFile>false</GenerateProgramFile>
+    <IsTestProject>true</IsTestProject>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <Compile Include="Tests.fs" />
+    <Compile Include="Program.fs" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
+    <PackageReference Include="MSTest.TestAdapter" Version="3.0.4" />
+    <PackageReference Include="MSTest.TestFramework" Version="3.0.4" />
+    <PackageReference Include="coverlet.collector" Version="6.0.0" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\Homework1.fsproj" />
+  </ItemGroup>
+
+</Project>