Question: I started using atom as my editor for learning Javascript. I've followed a bunch of tutorials online and while my code looks exactly like it does in the tuts, for some reason I'm missing the Javascript behavior. Here is a simple example of my code that simply won't run out of atom, notepadd++ or notepad. In atom I use the atom-live-server, in notepadd i basiclaly open it on local host. ANyoe have any idea?

```
<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Document</title>
</head>
<body>
   <form name="login">
      <input type="text" placeholder="Username" name="UserID"><br>
      <input type="text" placeholder="Password" name="Pass"><br>
      <input type ="button" onclick="check(this.form)" value="Login"/>
   </form>

   <script type="text/javascript">
      function check(form){
         if(form.userId.value=="" || form.pass.value==""){
            alert("BLAHBLAHBLAH")
         }
      }
   </script>
</body>
</html>

```

Answer: 
As suggested by @qwertyman in the comments 

1. remove all invalid edges i.e edges whose difference is greater than 1
2. Now we have a forest, for each forest calculate the diameter as it is given in @Filip Kočica solution
3. The answer would be the max diameter out of all forests
Let `longest_desc[a]` be the longest 1-by-1 descending path going down from a
Similarly `longest_asc[a]`, the longest 1-by-1 incremental path going down from a 

For a fixed root R, the answer would be `longest_desc[R] + longest_asc[R] - 1`.

A brut force solution would do 2 dfs/bfs traversals from each node X to compute `longest_asc[X] and longest_desc[X]` and then merge them together. The resulting runtime complexity would be `O(n^2)`.

But we can actually do better using dynamic programming:

```
longest_asc[X] = max(longest_asc[Y in children[X]] with Y = X + 1)
longest_desc[X] = max(longest_desc[Y in children[X]] with Y = X - 1)

```

Then we can compute all the values in a single DFS traversal => `O(n)` solution.