Strident Sardine, an Amazon engineer, interviewed Vermillion Tortoise in Python
Next largest in BST
1) Find the next largest node in a BST given the root and the target node. 2) How would you modify this if you wanted to find the next smallest? How would you modify this if you were not given the root node?
Feedback about Vermillion Tortoise (the interviewee)
Advance this person to the next round?
How were their technical skills?
How was their problem solving ability?
What about their communication ability?
Continue to write pseudo-code before coding it out, it still seems to help a lot by being a bridge between translating thoughts into implementation.
Feedback about Strident Sardine (the interviewer)
Would you want to work with this person?
How excited would you be to work with them?
How good were the questions?
How helpful was your interviewer in guiding you to the solution(s)?
The interview was very professional & included interesting follow-up questions - great job.
Vermillion Tortoise: Hey. Strident Sardine: Hi, how's it going? Vermillion Tortoise: Hey, good. Strident Sardine: Cool. So I was just looking over your details. This is for a junior engineering position, is that correct? Vermillion Tortoise: Yes. So it's probably for an SDE 2 position. I'm not sure. I think that might be mid-level for
Amazon, but I would probably be looking to enter in as a sort of lower level SDE 2. Strident Sardine: Okay, okay. Alright, I guess I would usually consider that more on the senior side, yeah. Okay, well, okay, maybe I'll think of a different question then. Okay cool, let's go with this one and yeah and if we have time, we'll do another question or I can follow up with some follow-up questions. Vermillion Tortoise: That sounds great. Strident Sardine: Alright, and then you can just pick whatever language you'd like, but I'll post the question here. Vermillion Tortoise: Okay, I'll go ahead and choose the language. There you go. Strident Sardine: Okay, so you're dealing with a binary search tree. So that means that for each node, it has the following properties where the left subtree is less than the root and the root is less than the right subtree. So when you do an in order traversal, that would result in going from the smallest element up to the largest element. So, let's say I give you a node in the BST. I want you to get me the in order successor. Vermillion Tortoise: Okay. Alright, so let's take a look here. So, I'll go ahead and just do an example to make sure that I understand the problem. So let's say we have a tree that's five... Okay, so here's an example binary search tree, this one happens to be balanced. So I'm just given any node in a BST, get the in order successor to that node. Let's see, the successors is the next node and in the traversal you can assume the node is valid and exist somewhere in the tree. Okay. So, let's say that we're given five, the root node. We want to return six. Another example given six, you want to return seven. Okay, let's see. Given eight, an edge case here, we would want to return none Does that work for you? Strident Sardine: Yeah. Vermillion Tortoise: Let's see, any other interesting cases? Okay, so that's the gist of it. We'll assume that our our BST is well formed so we don't have to check to make sure that the BST property holds. Okay, if I think of any other edge cases, I'll keep track of them here, but yeah. Strident Sardine: Yeah, you can make that assumption. Vermillion Tortoise: Okay, great. So. Okay. I think there are a couple cases here. So there is the case... I guess sort of a brute force solution is to traverse the tree in order and store each node in output list, and then we could traverse this and return node after given node. Strident Sardine: So what would be the expected time complexity of that? Yeah, looks like you're getting at that. Vermillion Tortoise:
O(1)time complexity because we're just gonna... well it's really
O(n + n), but that simplifies down to
O(n)and then... but our space is where we take the hit because now we've got to traverse the tree and we've also have to store it, now put it in an array. So I think that really our best conceivable runtime from our time perspective is to hit... let's see we should be able to do some type of binary search, given that it's a binary tree, so we shouldn't have to traverse every single element. So I think it's feasible to shoot for something in
O(log n)time and then depending on how we implement it, if we do it recursively our space would be
O(log n)or if we have an iterative approach, we might be able to pull it off in
O(1)space. Strident Sardine: Okay, okay, so let's talk about some improvements you can make to the brute force. Yeah, let's try to improve the time. I'm okay with the space being either. Yeah, let's talk about how we can improve the time. Vermillion Tortoise: Okay great, so what we can do is a typical binary search through the binary search tree. So what we can do is try to find our given element and then maybe do some extra processing or keep track of a couple different elements that will allow us to find the successor. So what we can do... Let's see... So just walking through this example by hand, given five. So we have found... in this case, the root node is the node we're searching for and there is a right child that we will return the right child. Oh, excuse me, that's not the case. Let's talk about the different cases. So, there's the case where... I'll call it the search node... search node has right child. It's the smallest element in right subtree, so that's the example there. We see that we have five, five has a right child, so we want to get the smallest element from that subtree, which will be the in order successor to that node. Let's see, another case here. Given six, we return seven, so in that case... Let's see... so we find six, six does not have any children... or I should say it doesn't have any... So say if a node has no children, then we want to return the parent, because the parent will be the next larger element. Okay, let's see and then there's also the case where we do not have a successor. So our search node has no children and in this case, we will return none. Okay, so walking through our example, let's see, let's take another one. Let's take three. So applying our algorithm, we do typical binary search we see that three is less than the root node, five. So we traverse left. We see that three is the node that we're searching for, so find the minimum element in the right subtree, which is four. Okay, so that works. Let's see, let's say that we're given seven. So we traverse the binary tree, find seven, and then we want to... let's see... find the smallest element in the right subtree, which is eight, okay. So this looks good to me, so I'm gonna write out a little bit of pseudocode here. Strident Sardine: Okay. Vermillion Tortoise: Okay, so what we want to do... let's see... So we'll have a recursive function. It's going to basically be walking through the cases, let me just think for a moment if there's anything I haven't considered. Okay. I think that the cases kind of handle my pseudo code, so I'm gonna go ahead and jump in. Strident Sardine: Okay. Can you explain each case very briefly? Vermillion Tortoise: Sure, so basically what we're gonna do is we're going to search our binary tree for the element. I think another assumption that I need to list is that we need to find out if that node exists. Should I assume that node exists in the tree or that it could be... Okay, oh there it is, okay, thank you. Okay, so we're going to do a binary search to identify our node. Once we find the node, there are a couple cases we have to consider. In the case where the node has a right child, we need to return the smallest element in the right subtree, which is the smallest element that's larger than our search node. If that node has no children, oh I see... I've repeated myself here, okay. Okay, so when I say if search node has no children, returning the parent is not the thing to do. What I need to do is return, let's see... Next largest number. So what I can do is as I'm traversing my binary search tree, If I traverse left, what I can do is I can save the node at which I traverse left as my next largest number. So that will ensure that if I end up in the case where my search node has no child, I will have stored previously the next largest number. And I will initialize this to none, which will handle the case where there is no larger value. Thanks for catching that. So just really quickly to run through an example, let's say that we're given four. So at five, I see that four is less than five, so as I traverse left, I'll save that node value, which is five. So five will be our next largest number. I'll hit three, see it's greater than three, find the minimum element there... Or excuse me, and then I find four and see that there's no children, and so I return the next largest number. Strident Sardine: Got it, okay. Vermillion Tortoise: Okay great. And then in terms of... I'll just get the algorithm down first and then we can talk through some test cases. So I'm going to do get successor, which will take a node and next largest. We'll say if... So in our two cases here... Okay, so if node does not exist, then we need to return next largest. Okay. Let's see, that's our first case. And then let's see here. Strident Sardine: Okay, so this is like the return value, is that right? Vermillion Tortoise: Yeah, so I'm gonna have another helper function up here that will be get smallest, given a node, and that will return the smallest. I'll just leave that there for now, but basically if we traverse to the point where there's not a node, then we'll return the next largest value. Let's see. Let's see, it has a right node that we want to return. Let's see. Get smallest of node.right? Otherwise, let's see... Otherwise we want to return getSuccessor of node.left. Next largest will be node.now. So I'll revisit this but just to get my whole idea down here, so when we get the smallest current node, we'll say... So if the node does not have a right value, then we will return node.val. Otherwise we will return
getSmallest(node.right)?Okay, so when we get this smallest value, let's say that we're given seven, we want to traverse left as far as possible. So if the node does not have a value on its left, then we know that we have found our minimum element in that subtree. Otherwise we want to continue traversing left until we found it. Okay. Strident Sardine: I see. Vermillion Tortoise: Okay, so that will improve how we get our smallest element. And then when we get our successor, what is it? Okay, so when we get our successor, if our node does not exist, then we know... I need to do the binary search property in here. Okay. So there's one additional layer on here that I need to take care of. It's successor needs to be passed the node that we've found. So we'll say find node, which will take in a node, and our value that we're searching for which is... we'll call it m. So say if node.val equals None, return node. Else if node.val is less than num we need to go, right. Otherwise we need to go left and... Okay. So this function here will return the node in the tree. Okay, hold on it. I think that I need to consider my inputs a little bit more closely here. So, I'm given a node in a BST. Okay, so when I'm given the node, the node itself, not the value of the node, is that correct? Strident Sardine: Yeah. Vermillion Tortoise: Okay got it. So that's sort of superfluous then, I coded this up thinking that I would have the node value but I have the node itself, so I can just start directly from the node. Strident Sardine: Okay, let's hang on, let's keep that there. You don't need to necessarily remove it. Okay, so, I think here you probably meant elif. Vermillion Tortoise: Oh, yes, thank you. Strident Sardine: Yeah, I see what you're saying. Okay, so where are you going to call find node or if at all? Vermillion Tortoise: No, I think that's a good point. Find node would only be called if we had the the number that we wanted to search for in the tree but not the node itself, so finding node in this example would not be called yet. Strident Sardine: Fair enough. Okay, so how would I call your function that actually gets me the successor? Vermillion Tortoise: Okay great, so let's say down here, what we'll go ahead and do is let's say that we had... I'll just kind of make up a... So let's say that search node equals... We'll just say that search node is some know that already exists in a binary search tree and so I'd say,
getSuccessor(node). And what that would do is handle the case where we do not have a next largest value. So basically, walking through this, so let's say that our search node is... Let's say that it's five. So given five, we want to find six. I see the issue here, okay. So I think I'm getting a little tangled up here, but I think I really hang on, so it's key that I walk through my binary search from the root node, because if I'm just given a node such as six, I won't be able to access it's successor. So when I do... so I do need to call... Let's see. Okay, I think I need to combine my binary search with my get successor, so basically get successor would take a root node, a search node, and then the next largest. So we have our node, search node, next largest, okay. So, to back things up here a little bit, so when we are... Let's see. Okay, I think I need to just step back and think about it from pseudocode. Strident Sardine: Sure. Vermillion Tortoise: Okay, so the first thing that I need to do is traverse binary tree until node is found, keeping track of next largest. Okay. Once I have found the next largest, or excuse me, until the search node is found. Okay, so once I have found the search node, then I have my cases to considers. Okay, got it. So that's the point at which I would handle those two cases, but in the meantime,
getSuccessorwould have a built-in binary search. So, given our node, what we want to do is let's handle the binary search here. So if, searchNode.val is greater than node.val, then we want to traverse right. Okay. Else if the search node is less than node, the current node, then we want to traverse left. And when we do so, we want to update next largest. Otherwise we have the case where we have found our node and we have to consider these two cases listed above. So, now that we've found the node, if let's see... Not node.left and not node.right, then we can return our next target. Okay. If we have a right subtree, then we need to return get smallest of node.right? Okay, so I'm going to go ahead and remove this code here and then take another look and make sure that... Strident Sardine: Okay, that does seem to line up more with what you had originally stated. Vermillion Tortoise: Yeah. I'm sorry about that. I think that it's always good to go through a little bit more pseudocode on the front end. Okay, so in this case we're doing our binary search, so you know, let's go ahead and walk to an example here. Let's say that we're given six. So we call
getSuccessorwith the root node, our search node, and none. So what we'll do is if our search node value is greater than our root, which is five, we'll traverse right. Okay, so now we're at seven. So if our search node value is less than the current node's value, so we will update next largest to seven and we'll traverse to the left to six. Now we put that third conditional where the search node is equal to the node, so we see that our search node six has no children, so we'll return next largest which is seven. Okay. So let's walk through another one, let's say that it's eight. So in that case, our next largest will never get updated and it will remain none and then we will continue traversing right until we hit eight and we will return none which will indicate that there is not a larger value in our binary search tree. So let's see here. Okay, let's say that our given is five. So in the case that it's five, we immediately hit our third conditional. We see that the search node has a right subtree, so we need to get the smallest element from that right subtree, which will be guaranteed to be our accessor. So now we kick into the
getSmallestfunction given five. So, we passed that seven, so get smallest of seven. We see that seven does have a left branch and so we call get smallest of six. Six does not have any nodes to the left of it, so we will return six and six will be the successor to five. Okay. Strident Sardine: So, there's one thing about
Pythonthat I'm a little unclear on, which is that there does seem to be a situation where even if you fall into this else, you might not fall into either of these cases, and so what is the expectation if you know, it doesn't reach a return statement. Vermillion Tortoise: Oh okay, thanks for pointing that out. So, I think that so in that case, you're right, there's a there is a conditional here, that's not being handled correctly and I think that... Let's see... I see. So I think another example, so the three cases once we hit our node is that it has a right subtree, in which case we want the smallest element from the right. It has a left subtree, in which case... If it has a less subtree, so let's try to think about an example in which that's the case. We do not care if that has a left subtree. What we really care about is the right subtree. Strident Sardine: Yeah, I think you're right. So in the example below, if you were to have some value here on the left of 80, it doesn't seem to be affecting anything. Vermillion Tortoise: Right. Okay, thank you. Yeah, that's a great add, so what we really want to do is if not node.right. Strident Sardine: And so what about this method? Vermillion Tortoise: This method can go. Strident Sardine: Okay. Vermillion Tortoise: Yeah, it's built into get successor now. Strident Sardine: Okay, okay. And if necessary, we could just wrap this in a helper message that doesn't include next largest. Okay, no worries, you don't need to do that. Okay, so... okay. I think this seems more consistent with what you were walking through, even though when you're describing the it doesn't match up with what you're describing in the cases, but I think this is the more proper approach. So what is the space and time complexity at this point? Vermillion Tortoise: Okay great, so let's see here. So at this point, we are not traversing. We are at most traversing the depth of the tree. So our time complexity in that case is
O(log n)and then because this is a recursive function, we will have a space complexity also of
O(log n)from putting the calls on the call stack. Strident Sardine: So could you imagine a situation where it's not log of n? Vermillion Tortoise: So we know that for sure to find the number in the binary search tree is
O(log n). If the tree is balanced. So if our tree is unbalanced, in the worst case scenario we could have a tree where all the elements are increasing and so our depth of our tree is equal to the length of our tree, which is
O(n). So if our tree is unbalanced, then that is the worst case scenario. If our tree is balanced, then it will ensure
O(log n). Strident Sardine: Yeah, so is there a better way to represent the complexity? Vermillion Tortoise: Okay, so we could say... So typically you just write the worst case time complexity. Strident Sardine: Right, so based on what you described, is there better way to represent the time and space complexity instead of
O(n). Vermillion Tortoise: Oh okay, so instead of n, we could say d, we could say,
O(d), where d equals the depth of our maximum of that definition. Strident Sardine: Okay max recursion of the tree. Yeah. Now, what if I asked you to get me the in order predecessor to a node, what would change here? Vermillion Tortoise: Okay, great. So if we wanted the inorder predecessor, we would want to keep track of the next smallest. So our get successor would look like if our search value is less than our node value, or excuse me, if our search value is greater than our node value, we would go right, except we would update our next smallest instead of our next largest and then on line 53, we would just pass down next smallest, rather than updating it. And we would say if not node.left, we will return next smallest otherwise we would get the largest of node.left, so it's kind of an inverse approach. Strident Sardine: Okay, and it sounds like here you would just kind of swap the the pointers as well. What if I did not give you a root node? Vermillion Tortoise: Interesting. Strident Sardine: How would you find the successor? Okay sounds like when you're going to the right then that's not a concern. What about when you need to conceptually traverse up? Vermillion Tortoise: Right, okay, so let's say we're given a node like in your example here, we want to find the successor of say, 60 and we're just given that node, 60. So we would have to have an implementation of our binary search tree that kept track of the parent. So you would have no children, but would have a parent and so we'd say once we've found our value, if there were no children then we could traverse to the parent, which might be greater than or less than the current node. Strident Sardine: Correct. So what would be your terminating condition? Vermillion Tortoise: Got it, so I think that we would... So let's say that we are finding the successor and we're given sixty. Sixty has no children, but it has a parent. So we traverse up to the parent and we'd say if the parent is greater than sixty, then we know that we've found the successor, the next largest value. Let's see... if the parent is less than sixty, then we wouldn't need to traverse up from that parent. Strident Sardine: Sorry, so could you could you clarify just as a quick summary like what is the stopping point for navigating that one? Vermillion Tortoise: Sure, so the stopping point for navigating up is when our parent value is greater than our search node value. At that point we know that found likely a larger node. I'm trying to think of a case that would require you to traverse from the parent. Strident Sardine: Oh I see. Vermillion Tortoise: Okay, so there are two cases. Your parent is either larger than you or it's smaller than you. In the case where your parent is larger than you and you have no children, then you know that you found your successor. In the case where your parent is less than you, then you need to continue traversing to the next parent until you find one that is greater than your search node. Strident Sardine: I think that makes sense. What about for 80, like you were saying here. None of its parents are larger than it. Vermillion Tortoise: Okay, so in that case, we would end up traversing until the root node, in which case the root node has no parent and if we get to that position we know that 80 does not have a successor. Strident Sardine: Okay yeah and I think that makes sense because even with your current implementation, the greatest element in the tree has no successor, which makes sense. Vermillion Tortoise: Okay great. Strident Sardine: Okay cool, I think we're at 40 minutes, you know, we probably don't have time for a second question, but you know, I think this is a good stopping point if you can agree with that. Yeah, so you know, in terms of like my assessment, I would say definitely like this would be inclined to hire. A lot of good indicators going on here. Starting off with a complex example to derive like an algorithm, so that was a combination of like like getting clarification and doing some testing to make sure you have a plan of action before starting implementation, so definitely what we're looking for here and really like that you broke down the brute force and the most optimal scenario that could be possible here. Yeah, I think you might have skimmed a little bit in terms of walking through examples in that example tree that you gave, you know, you kind of had a bias for the right side of the tree and later on during the implementation you started to realize that you you made some some over generalized assumptions about when there's no children versus when there's no right child. Maybe you would have caught that if either you worked on the left side or maybe had a less complete tree, like say you removed the the four here and you tried to get the successor of three, then that might of helped you identify that part. However, I would say that even after that, you know, it seemed like only a minor adjustment when I pointed out that else clause that you were able to adjust and revise that pretty quickly, so I can definitely see you have pretty good problem solving skills and you do have a good methodology to tackling a problem, so a lot of premeditation before any type of implementation gets out there. You're already making sure you have a complete solution, even if it that solution is not correct you still try to flush it out as much as possible. It does seem like you do benefit from making the pseudocode, so I encourage you to continue doing that however trivial it may seem, after you've done everything else. It does seem to help you not lose your place in the implementation, which we saw a little bit of with the code that you had wrote initially and then kind of erased afterwards and kind of rewrote a lot of this main method. Definitely a lot of good indicators. I would not wave the coding missed up too heavily against you. It was a little... I mean before you got any code down, I was already kind of anticipating that you would finish fairly early. And then during the initial code write up, I was starting to have some doubts but you were able to recover very well. So, I'm glad to see that. And then, subsequently, you did follow up with verifying your code and being proactive about walking through it using the examples, going through it line by line, and you were able to get a lot of confidence that your code worked mostly, short of like that one else block and I think that's fine. You know, some code will have a bug or two and fact that you were able to identify it and adjust it was the part that I would say should be emphasized, that I thought was good. Okay. Yeah, in terms of the follow up questions, definitely really good job analyzing the time space complexity. My follow up questions, it seemed like you understand conceptually like what your code is doing and you're able to pivot to these different related challenges. So yeah, I think a lot of good indicators here, you know, I think you recognize like there's just a couple minor things that you can do to improve even more and just kind of give you almost like a 99% guarantee that you'll pass the coding interview. But there's not too much criticism I can give other than some nitpicky things. Vermillion Tortoise: I gotcha. Yeah, I definitely agree. I think that as soon as I started coding I kind of wish that I had done a little bit more pseudo code, so that's definitely some room for improvement there and then that conditional, but that makes sense. Strident Sardine: Yeah, yeah. I don't know if I really have anything else to say. Do you have any questions for me? Vermillion Tortoise: Yeah, so let's see... so I have a virtual on-site on Friday. I think... Strident Sardine: Which company? Vermillion Tortoise: With
Amazon. And it will be four 1 hour interviews. I think that there's you know 30 to 40 minutes slated for the technical question and then there's the behavioral after and I'm aware that
Amazonbehavioral is unique because they have these principles that they really value and you have to have a stories that speak each of the different leadership principles. So three of the technical interviews are coding algorithm and then there's one system design question. I think one thing I'm a little bit curious about is if in your interview or any interviews that you were a part of, if you guys did any object oriented stuff that you know, like object oriented design patterns and what the expectations there were? Strident Sardine: So I think that for a SD2 position, you're most likely going to have more of a system architecture interview rather than an object oriented interview. Those are slated more for junior candidates. Having said that, I would not be surprised if someone asked a little bit about object-oriented design. But I think you should primarily expect the architecture interview, not the object oriented one. Yeah and you're right, the leadership principles are heavily emphasized at
Amazon, as opposed to
Success in Tech. I'll write it down here. Actually, let me just grab the YouTube link. So this kind of gives you a demonstration of how to apply those concepts rather than purely teaching you about the concepts and I like it because it's a good demonstration of what you can realistically do in 45 minutes. As opposed to the Grokking the system design course, it's a little heavy in terms of how much they cover and so it leads to an unrealistic expectation that you should be able to go into that level of detail within 45 minutes. Vermillion Tortoise: Sorry, I just clicked the link and it started playing. Strident Sardine: So, I think this is one of those free resources I found that's very similar to grokking the system design that you don't want to spend like 80 bucks on it and were unsure. And then system design primer. And I think this link would be good for as a reference, you know, once you've gone through this github, this one kind of gives you a brief summary as a more of a refresher. Yeah, and I think it has some questions as well that you can work through. And yeah, so, you know, I think you're definitely doing the right thing in terms of preparing for system design if you're going in for mock interviews. It's definitely gonna be more emphasized for a senior engineer to know that type of stuff as opposed to a junior engineer for hopefully obvious reasons. Yeah in terms of behavioral, I think that one is gonna be a lot more about just practicing using mock interviews and really working on your stories, making sure they fit that star format, situate and behavior and and impact for action and result, same thing. So making sure that it's something kind of like pretty short and concise for the situation and then for the behavior and impact that's where you want to have a lot of emphasis on. Yeah, so you know after this we could connect and I can try to provide you some other resources as well. Vermillion Tortoise: Yeah, that'd be great. Thank you. Strident Sardine: Yeah, okay. Alright. Hopefully that gives you a better idea of how to prepare, but I think you know, you definitely doing the right things that sounds like. Vermillion Tortoise: Awesome, last really quick question for you. So are you working at Amazon currently? Strident Sardine: No. I'm no longer working there. I'm working at Oracle at the moment. Vermillion Tortoise: Okay, what were your thoughts about working at Amazon? Strident Sardine: I think you will have a... there's a lot of teams, so your experience will vary a lot from person to person. I think the the primary thing I would say you should focus on is the team that you're going to be on, what their culture is like, and potentially maybe what that department's organization and culture is like because I think your team will dictate the most about you're quality of your experience. Yeah, so my wife worked there before me and still works there after me, so she definitely has had a better experience than I have. So it is really variable. I think one thing that I have noticed in general across the board is that because Amazon is so data-driven, one of the drawbacks or benefits is that there really is a reason... there will be reasons to promote you as well as reason to not promote you, so there is a big bias depending on how well your manager and folks like you, they can really drive the direction of your ability to get promoted. So it can be easy or very difficult to gain seniority in the company. My difficult advice would be you want to come in at a baseline where you're happy to be there for a long time potentially. Vermillion Tortoise: Makes sense. Okay, well thank you for all the feedback, much appreciated. Strident Sardine: Yeah, okay. Quick question then, so where are you working currently? Vermillion Tortoise: Yeah, I was working at a startup and then unfortunately in April we ran out of money and so I was laid off as a result of that we were just kind of in the middle of fundraising and then coronavirus hit and our, you know, potential funding got pulled, so that's where I'm at currently. Strident Sardine: Yeah, I got it. I mean, that's not an uncommon situation to be in these days, so yeah, I totally understand but you know, it seems like you're still able to get interviews with these big tech companies so you know, I think you're doing the right thing and you know, it seems like you you have a pretty good chance assuming you know, you system design and behavioral skills are kind of similar to your coding skills. Vermillion Tortoise: Nice, thank you, yeah. Much appreciated. Strident Sardine: Okay. Alright, well, I don't have anything else. I'll go ahead and select like yes for keeping in touch or stay in contact, revealing the contact information. And yeah, so if you'd like to do that, you know, we can we can stay in touch. Vermillion Tortoise: Yeah, absolutely that sounds great. I'll do the same. Strident Sardine: Okay, cool. Alright have a good day. Vermillion Tortoise: Alright, take care you Amazontoo.